Logs no Linux: journalctl, /var/log, rsyslog e logrotate
Nas distribuições Linux atuais, os logs são coletados pelo journald e lidos com o comando journalctl: journalctl -u nginx mostra os registros de um serviço, -f acompanha em tempo real, e --since e -p filtram por horário e gravidade. Logs em texto ficam em /var/log, gerados pelo rsyslog ou pelo próprio aplicativo, e o logrotate comprime e apaga os antigos periodicamente para o disco não encher.
Quando um serviço cai de madrugada, a resposta quase sempre está nos logs; a questão é saber onde procurar. Nas distribuições atuais (Ubuntu, Debian, RHEL, Fedora, Arch), os eventos são coletados pelo serviço journald e lidos com o comando journalctl. Em paralelo, muitos programas gravam arquivos de texto em /var/log, e o tamanho deles é controlado pelo logrotate. A seguir, como trabalhar com os logs do journalctl no Linux na prática, onde ficam os demais registros e como não perder informações importantes na rotação.
Onde ficam os logs no Linux
São três fontes, e vale manter este mapa na cabeça:
- journald — o journal binário do systemd. Recebe stdout e stderr de todos os serviços, as mensagens do kernel e o syslog. Fica em
/var/log/journal/(permanente) ou em/run/log/journal/(até a reinicialização). - /var/log — arquivos de texto. São gravados pelo
rsyslog(por exemplo,/var/log/syslog,/var/log/auth.log) ou pelos próprios aplicativos: nginx, PostgreSQL, MySQL. - Buffer circular do kernel — mensagens de drivers e hardware, exibidas pelo
dmesgou pelojournalctl -k.
| Arquivo | O que contém |
|---|---|
/var/log/syslog (Debian/Ubuntu) | log geral do sistema |
/var/log/messages (RHEL/Fedora) | o mesmo na família Red Hat |
/var/log/auth.log ou /var/log/secure | logins, sudo, SSH |
/var/log/kern.log | mensagens do kernel |
/var/log/dpkg.log, /var/log/apt/ | instalação de pacotes |
/var/log/nginx/ | access.log e error.log do servidor web |
/var/log/wtmp, /var/log/btmp | registros binários de login, lidos com last e lastb |
A maioria dos arquivos em /var/log é acessível somente pelo root ou pelo grupo adm, por isso os comandos de leitura muitas vezes precisam de sudo.
journalctl: comandos básicos
Sem argumentos, o journalctl mostra todo o journal, desde os registros mais antigos, no paginador less. Raramente isso é útil: normalmente o recorte é feito logo de início.
journalctl # todo o journal, do mais antigo ao mais recente
journalctl -e # abrir já no fim
journalctl -n 50 # últimas 50 linhas
journalctl -r # ordem inversa, os mais novos primeiro
journalctl --no-pager # sem o less, útil em scripts e com grep
Dentro do paginador valem as teclas do less: / para buscar, G para ir ao fim, q para sair. Linhas longas são cortadas pela largura da tela; as setas para a esquerda e para a direita rolam o texto.
Logs de um serviço específico: journalctl -u
O cenário mais comum é ver o que uma unit do systemd registrou. Não é preciso procurar arquivos nem usar grep:
$ sudo journalctl -u nginx -n 20
Oct 14 03:12:41 web1 systemd[1]: Starting nginx.service - A high performance web server...
Oct 14 03:12:41 web1 nginx[1834]: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
Oct 14 03:12:41 web1 systemd[1]: nginx.service: Control process exited, code=exited, status=1/FAILURE
Oct 14 03:12:41 web1 systemd[1]: nginx.service: Failed with result 'exit-code'.
A opção -u pode ser repetida: journalctl -u nginx -u php8.2-fpm mostra os dois serviços intercalados por horário, o que ajuda quando o erro acontece na divisa entre eles. Para units de usuário (systemctl --user), use journalctl --user -u nome.
Logs em tempo real: journalctl -f
sudo journalctl -u nginx -f
É o equivalente ao tail -f: o comando mostra os últimos 10 registros e fica aguardando os novos. É útil manter isso em outro terminal enquanto você reinicia o serviço ou reproduz o erro. Para sair, use Ctrl+C.
Filtros por horário e por inicialização
Se você sabe quando aconteceu o problema, delimite o período com --since e --until. Eles aceitam datas exatas e valores relativos:
journalctl --since "2026-10-14 02:50" --until "2026-10-14 03:30"
journalctl --since "1 hour ago"
journalctl --since yesterday --until today
journalctl -u nginx --since "10 min ago"
Outro recorte útil é por inicialização do sistema. Se o servidor reiniciou sozinho, a causa é procurada no fim da sessão anterior:
$ journalctl --list-boots
-2 8f1c... Sat 2026-10-12 09:01:12 UTC Sun 2026-10-13 22:47:03 UTC
-1 a7d2... Sun 2026-10-13 22:48:30 UTC Tue 2026-10-14 03:05:51 UTC
0 c3e9... Tue 2026-10-14 03:07:02 UTC Tue 2026-10-14 09:15:40 UTC
$ journalctl -b -1 -e # fim da inicialização anterior
$ journalctl -b # apenas a inicialização atual
A lista de inicializações só está disponível se o journal é guardado em disco. Como ativar isso, veja mais abaixo, na seção sobre a configuração do journald.
Filtro por gravidade: journalctl -p
Cada registro tem uma prioridade syslog, de 0 a 7. A opção -p mostra o nível indicado e todos os mais graves:
| Código | Nome | Quando é usado |
|---|---|---|
| 0 | emerg | o sistema está inoperante |
| 1 | alert | é necessária intervenção imediata |
| 2 | crit | erro crítico |
| 3 | err | erro |
| 4 | warning | aviso |
| 5 | notice | evento relevante, mas normal |
| 6 | info | mensagem informativa |
| 7 | debug | depuração |
journalctl -p err -b # todos os erros desde o início da inicialização
journalctl -p warning..err -u ssh # faixa de níveis para um serviço
O comando journalctl -p err -b é uma boa primeira verificação depois de reiniciar ou atualizar o sistema: em segundos mostra o que deu errado.
Busca e outros filtros
O journald guarda campos estruturados em cada registro, e é possível filtrar por eles sem o grep:
journalctl _PID=1834 # pelo número do processo
journalctl _COMM=sshd # pelo nome do programa
journalctl _UID=1000 # pelo usuário
journalctl /usr/sbin/sshd # pelo caminho do executável
journalctl -k # somente mensagens do kernel (como o dmesg)
journalctl -t CRON # pelo identificador do syslog
journalctl -g "Out of memory" # busca no texto, com expressão regular
A opção -g (--grep) apareceu no systemd 237; em sistemas mais antigos, use o pipeline comum journalctl --no-pager | grep .... Filtros de campos diferentes se combinam com "E", então journalctl -u nginx -p err --since today mostra apenas os erros de hoje do nginx.
Formatos de saída
A opção -o muda o formato. As variantes mais úteis:
-o short-iso— horário no padrão ISO 8601, útil para comparar com os logs do aplicativo.-o verbose— todos os campos do registro, incluindo_SYSTEMD_UNIT,_PID,_BOOT_ID.-o jsonoujson-pretty— para processar com scripts ou com ojq.-o cat— somente o texto da mensagem, sem data e sem host.
journalctl -u myapp -o json --since today | jq -r '.MESSAGE'
Configurar o journald: armazenamento e tamanho
As configurações ficam em /etc/systemd/journald.conf; as alterações são mais bem feitas em arquivos de /etc/systemd/journald.conf.d/*.conf. O parâmetro principal é Storage:
persistent— o journal é gravado em disco, em/var/log/journal, e sobrevive à reinicialização.volatile— apenas na memória, em/run/log/journal.auto(padrão) — em disco, se o diretório/var/log/journalexistir.
Algumas imagens mínimas não têm esse diretório, e o histórico desaparece após a reinicialização. Para ativar o armazenamento permanente:
sudo mkdir -p /var/log/journal
sudo systemd-tmpfiles --create --prefix /var/log/journal
sudo systemctl restart systemd-journald
Para que o journal não ocupe o disco inteiro, defina limites:
# /etc/systemd/journald.conf.d/size.conf
[Journal]
Storage=persistent
SystemMaxUse=500M
MaxRetentionSec=1month
Por padrão, o SystemMaxUse é 10% do tamanho do sistema de arquivos, mas não mais que 4 GB.
Como limpar o journal do journalctl
$ journalctl --disk-usage
Archived and active journals take up 1.8G in the file system.
sudo journalctl --vacuum-size=300M # manter no máximo 300 MB
sudo journalctl --vacuum-time=2weeks # apagar registros com mais de duas semanas
sudo journalctl --rotate # fechar os arquivos ativos para que possam ser apagados
Não é recomendado apagar arquivos de /var/log/journal com rm: o vacuum faz o mesmo de forma segura e não mexe no arquivo ativo.
rsyslog: logs de texto clássicos
O rsyslog é o daemon que recebe mensagens syslog (inclusive as repassadas pelo journald) e as distribui em arquivos segundo regras. A configuração fica em /etc/rsyslog.conf e em /etc/rsyslog.d/*.conf. Uma regra é formada por um seletor origem.nível e uma ação:
# /etc/rsyslog.d/50-default.conf (trecho)
auth,authpriv.* /var/log/auth.log
*.*;auth,authpriv.none -/var/log/syslog
kern.* -/var/log/kern.log
O hífen antes do caminho indica gravação sem sincronizar o disco a cada linha: é mais rápido, mas, em caso de queda, as últimas linhas podem se perder. Depois de alterar a configuração, verifique a sintaxe e reinicie o serviço:
sudo rsyslogd -N1
sudo systemctl restart rsyslog
O motivo principal para manter o rsyslog junto do journald é o envio dos logs a um servidor central. Uma linha basta para enviar tudo por TCP:
# /etc/rsyslog.d/90-remote.conf
*.* @@logs.example.com:514
Um único @ significa UDP; dois @@ significam TCP. Se o servidor cair por completo, uma cópia dos logs continua em outra máquina. Para gravar sua própria mensagem no log do sistema a partir de um script, use o logger:
logger -t backup -p user.err "Backup do banco falhou"
journalctl -t backup -n 5
logrotate: rotação de logs
Logs de texto crescem sem limite até que alguém os corte. Quem faz isso é o logrotate: uma vez por dia (pelo cron ou pelo timer logrotate.timer), ele renomeia o arquivo atual, comprime os antigos e apaga os mais velhos. As configurações gerais ficam em /etc/logrotate.conf, e as regras de cada programa, em /etc/logrotate.d/.
# /etc/logrotate.d/myapp
/var/log/myapp/*.log {
daily
rotate 14
compress
delaycompress
missingok
notifempty
create 0640 myapp adm
postrotate
systemctl reload myapp > /dev/null 2>&1 || true
endscript
}
| Diretiva | Significado |
|---|---|
daily / weekly / size 100M | quando rotacionar |
rotate 14 | quantos arquivos antigos manter |
compress, delaycompress | comprimir com gzip, mas deixar o arquivo mais recente sem compactar |
missingok, notifempty | não reclamar se o arquivo não existir, não rotacionar um arquivo vazio |
create 0640 user group | permissões do novo arquivo |
copytruncate | copiar e zerar o arquivo — para programas que não sabem reabrir o log |
postrotate ... endscript | comando executado após a rotação, normalmente um sinal para o aplicativo reabrir o arquivo |
Para testar a regra sem alterar nada, ou forçar a rotação agora:
sudo logrotate -d /etc/logrotate.d/myapp # teste a seco com depuração
sudo logrotate -f /etc/logrotate.d/myapp # rotacionar agora
Erro comum: esquecer o postrotate ou o copytruncate. Nesse caso, o aplicativo continua gravando no app.log.1 renomeado, pelo descritor antigo, e o novo app.log fica vazio.
Como ler logs de texto
Para os arquivos de /var/log, as ferramentas padrão bastam:
sudo tail -n 100 /var/log/syslog # últimas linhas
sudo tail -F /var/log/nginx/error.log # acompanhar, mesmo após a rotação
sudo less +G /var/log/auth.log # abrir no fim
sudo zgrep "Failed password" /var/log/auth.log.*.gz # buscar em arquivos compactados
sudo grep -c " 500 " /var/log/nginx/access.log # quantas respostas 500
Repare no tail -F com letra maiúscula: diferentemente do -f, ele reabre o arquivo quando o logrotate o substitui.
Passo a passo para investigar uma queda
O cenário "o serviço caiu de madrugada" é mais fácil de investigar seguindo esta ordem:
systemctl status myapp— estado atual e últimas linhas do log.journalctl -u myapp --since "03:00" --until "03:30"— o que o serviço registrou no momento da queda.journalctl -p err -b— há outros erros no sistema no mesmo período?journalctl -k --since "03:00" -g "Out of memory|Killed process"— o OOM killer do kernel encerrou algum processo?- Os logs do próprio aplicativo em
/var/log/myapp/, incluindo os arquivos.gz. - Se o servidor reiniciou,
journalctl -b -1 -e.
Resumo
Para o dia a dia com logs no Linux bastam alguns comandos: journalctl -u para um serviço, -f para acompanhar, --since e -p err para restringir a busca, e -b -1 para analisar uma reinicialização. Os registros de texto ficam em /var/log; o rsyslog os organiza e envia, e o logrotate e o journalctl --vacuum-* impedem que os logs encham o disco. O trabalho com journalctl, rotação e diagnóstico de carga é praticado na aula do curso de Linux.
Perguntas frequentes
Por que o journalctl mostra apenas os registros da última inicialização?
O journal está sendo guardado na memória (/run/log/journal). Crie o diretório /var/log/journal ou defina Storage=persistent no journald.conf e reinicie o systemd-journald.
Como permitir que um usuário comum leia o log do sistema sem sudo?
Adicione-o ao grupo systemd-journal (ou adm, no Debian e no Ubuntu): sudo usermod -aG systemd-journal nome, depois faça logout e login novamente.
É possível ver o journal de outro sistema, por exemplo de um disco montado?
Sim, informe o diretório do journal com a opção -D: journalctl -D /mnt/var/log/journal. A opção --file lê um arquivo .journal avulso.
O rsyslog é necessário se já existe o journald?
Não é obrigatório. Ele é útil quando se precisa de arquivos de texto para ferramentas antigas ou do envio de logs a um servidor central; em muitas imagens mínimas ele nem é instalado.
Como exportar os logs de um serviço para um arquivo e enviar a um colega?
Execute journalctl -u nome --since today --no-pager > servico.log — o resultado é um arquivo de texto comum.
Este tema é abordado em profundidade, com prática, no curso “Linux: с нуля до уверенного администрирования”.
Ir para o curso