journalctl: analisar os logs do systemd e conservá-los

Publicado a 21 min de leitura

Janelas de tempo, filtros por unit, prioridades e padrões de pesquisa: como recortar em três ou quatro comandos exatamente o excerto que corresponde à avaria. Mais um journal que sobrevive aos reinícios e as mensagens de erro na íntegra.

Um servidor que tem alguma coisa errada já registou, quase sempre, tudo o que aconteceu. A dificuldade não é a falta de informação, mas a quantidade em que ela está enterrada. Quem invoca o journalctl sem argumentos aterra no início do journal e passa semanas de mensagens antigas. Este guia mostra como recortar, em três ou quatro comandos, exatamente o excerto que corresponde à avaria.

O artigo Criar um serviço systemd apresenta as formas básicas -u, -b e -f. Aqui trata-se de tudo o que vem a seguir: janelas de tempo, filtros, prioridades, formatos de saída, a conservação permanente do journal, limites de tamanho, mensagens do kernel e padrões de pesquisa prontos a usar.

Todas as indicações referem-se a Debian 13 (trixie), Debian 12 (bookworm), Ubuntu 24.04 LTS e Ubuntu 22.04 LTS. Os comandos estão escritos para funcionamento como root. Se trabalhar com um utilizador normal, anteponha sudo a cada comando.

Antes de alterar seja o que for: o caminho de volta

Ler o journal não tem qualquer risco, nenhum comando de pesquisa deste artigo altera o que quer que seja no sistema. Arriscadas são exatamente três coisas, e todas elas só surgem mais à frente.

Um sistema de ficheiros cheio. Sem um limite próprio, o journal ocupa até dez por cento do sistema de ficheiros, com um teto de quatro gigabytes. Num disco pequeno, um /var cheio é o caminho mais curto para um servidor que deixa de aceitar qualquer início de sessão.

Uma gralha na configuração. O systemd ignora chaves desconhecidas em vez de parar o serviço. O seu limite fica escrito no ficheiro, mas não produz efeito, e ninguém o avisa disso por iniciativa própria.

Uma limpeza precipitada. O journalctl --vacuum-time=1d apaga de forma irreversível, incluindo as provas que anda justamente à procura.

A via de salvação para o pior cenário: nos servidores root KVM e nos servidores dedicados da KernelHost não existe IPMI nem iDRAC. O acesso que funciona mesmo sem rede é a consola VNC na área de cliente. Ela está ligada à camada de virtualização, ou à própria ligação física, e não à pilha de rede do sistema convidado. Inicie sessão ali uma vez antes, e certifique-se de que conhece a palavra-passe de root.

Levantamento em cinco comandos

systemctl --version | head -n 1
systemctl is-active systemd-journald
journalctl --disk-usage
ls -d /var/log/journal /run/log/journal
df -h /var

O quarto comando é o mais importante: responde à questão de saber se o seu journal sobrevive a um reinício e devolve No such file or directory para o diretório que não existir. Todas as alterações deste artigo vão parar, mais à frente, a um ficheiro próprio em /etc/systemd/journald.conf.d/. O /etc/systemd/journald.conf original fica intocado, e a reversão resume-se a dois comandos: apagar o ficheiro, reiniciar o serviço.

Delimitar a janela de tempo em vez de percorrer tudo

Quase todas as avarias têm uma marca temporal. É por aí que a análise começa, e não pelo nome do serviço.

journalctl --since "-30min"
journalctl --since "2026-09-02 03:10" --until "2026-09-02 03:20"
journalctl --since yesterday --until today

O --since e o --until têm as formas curtas -S e -U. Como indicação de tempo, o journalctl aceita valores absolutos no formato 2026-09-02 03:10:00, datas sem hora (vale então a meia-noite), as palavras-chave yesterday, today, tomorrow e now, além de indicações relativas como -1h, -30min ou 2 days ago.

Aqui esconde-se uma armadilha que custa muito tempo: o journalctl trabalha na hora local do servidor, ao passo que as aplicações registam muitas vezes em UTC. Quem copiar sem pensar uma marca temporal de um log de aplicação para o --since procura, no verão, duas horas ao lado do acontecimento. Verifique o fuso, ou peça logo tudo em UTC:

timedatectl
journalctl --since "2026-09-02 01:10" --until "2026-09-02 01:20" --utc --no-pager

Passo de verificação: se a resposta for -- No entries --, ou a janela está demasiado apertada, ou o fuso está errado. Alargue a janela para uma hora, a título de teste, antes de duvidar dos filtros.

Arranques do sistema como janela de tempo

Muitas vezes, o excerto certo não é um intervalo de horas, mas um arranque do sistema. O -b sem valor refere-se ao arranque em curso, o -b -1 ao anterior.

journalctl --list-boots --no-pager
journalctl -b -1 -p err --no-pager

A lista mostra uma linha por arranque, com um índice; o arranque em curso leva o 0. Se aparecer apenas essa única linha, é provável que o journal não esteja sequer a ser guardado de forma permanente. Nesse caso, o -b -1 responde no Debian 13 com No journal boot entry found for the specified boot (-1) e no Ubuntu 24.04 com No journal boot entry found from the specified boot offset (-1). Não é uma avaria, é o aviso de que ali não há nada a obter.

Filtrar por serviço, processo e prioridade

A unit, e porque é que o nome tem de estar exato

journalctl -u nginx.service --since "-2h" --no-pager

O -u compara por igualdade, não por semelhança. Daí nasce um erro particularmente desagradável, porque não produz qualquer mensagem de erro: journalctl -u mysql devolve, num sistema Debian com MariaDB, -- No entries --, apesar de o journal estar cheio de mensagens da base de dados. Ali, mysql.service é apenas um nome alternativo para mariadb.service. O systemctl resolve esses nomes alternativos, mas o journal guarda tudo sob o nome verdadeiro. Recebe, portanto, uma resposta errada que não tem o aspeto de um erro.

O nome verdadeiro obtém-se a partir do próprio journal. O -F lista todos os valores que um campo alguma vez assumiu ali:

journalctl -F _SYSTEMD_UNIT | sort | grep -i sql

Além disso, o -u aceita padrões, o que retira gravidade à questão:

journalctl -u "mysql*" -u "mariadb*" -n 60 --no-pager

A mesma verificação compensa no Ubuntu 24.04 para o SSH, porque ali o serviço arranca através de uma ativação por socket e os inícios de sessão não ficam obrigatoriamente sob o nome esperado:

journalctl -F _SYSTEMD_UNIT | grep -i ssh

Identificador em vez de unit

Além da unit existe o identificador do remetente, ou seja, aquilo que o syslog clássico regista como nome do programa. O filtro para isso é o -t:

journalctl -t sshd -t sshd-session -n 50 --no-pager

Porquê dois? Desde a versão 9.8, o OpenSSH transfere as sessões para um processo próprio, o sshd-session. No Debian 13 (OpenSSH 10.0), sob -t sshd fica por isso apenas o registo de que o serviço está à escuta, ao passo que cada início de sessão fica sob -t sshd-session. O Debian 12 (9.2), o Ubuntu 24.04 (9.6) e o Ubuntu 22.04 (8.9) não conhecem esta divisão. Quem no Debian 13 filtrar só por -t sshd julga estar perante um servidor calmo, quando na verdade cada tentativa está a ser registada. Mais robusto é o caminho pela unit, porque os processos filhos pertencem à mesma:

journalctl -u ssh --since "-24h" --no-pager

Campos arbitrários, e como se combinam

Cada entrada traz campos que pode escrever diretamente como filtro, por exemplo _COMM (nome do programa), _PID, _UID, _SYSTEMD_UNIT ou _TRANSPORT. As regras de combinação são muitas vezes mal presumidas:

  • Dois filtros sobre campos diferentes combinam-se com E.
  • Dois filtros sobre o mesmo campo combinam-se com OU.
  • Um único sinal de mais entre dois grupos combina esses grupos com OU.
journalctl _SYSTEMD_UNIT=ssh.service _UID=0 --since "-1h" --no-pager
journalctl _SYSTEMD_UNIT=ssh.service + _SYSTEMD_UNIT=nginx.service --since "-1h" --no-pager

Os nomes dos campos escrevem-se em maiúsculas e a comparação é feita sobre o valor completo. Um journalctl unit=nginx não é, por isso, um filtro por parte do texto, mas um erro de sintaxe, que o journalctl assinala com Failed to add match.

Prioridades

Cada entrada traz um nível de urgência de 0 a 7. O -p filtra por esse nível, sempre incluindo todos os níveis mais urgentes: -p err mostra também crit, alert e emerg.

NívelNomeSignificado
0emergSistema inutilizável
1alertIntervenção imediata necessária
2critErro crítico num componente
3errErro, uma tarefa ficou por fazer
4warningAviso, o funcionamento continua
5noticeDigno de nota, mas normal
6infoMensagem normal de funcionamento
7debugApenas para diagnóstico de erros
journalctl -b -p err --no-pager
journalctl -u nginx.service -p 2..4 --since "-24h" --no-pager

E agora a armadilha em que a filtragem por prioridade falha com regularidade: aquilo que um serviço escreve na saída padrão fica no journal, por predefinição, como info, mesmo que tenha saído pela saída de erro padrão. Um programa que imprime uma exceção com stacktrace aparece assim como uma inofensiva mensagem de funcionamento, e o -p err esconde-a. Só recebem um nível adequado os programas que escrevem diretamente contra a interface do journal ou que antepõem às suas linhas um prefixo syslog como <3>. Nos serviços próprios, filtre por isso pela unit e pelo texto; nos serviços de sistema e no kernel, o -p é bem útil.

Pesquisa por texto

journalctl -u nginx.service --since "-24h" --grep "upstream timed out" --no-pager

O --grep (forma curta -g) pesquisa exclusivamente o texto da mensagem, não os restantes campos. As maiúsculas e minúsculas são ignoradas automaticamente enquanto o padrão estiver todo em minúsculas; assim que surja uma maiúscula, a comparação passa a ser exata. Ambos os comportamentos se podem forçar com --case-sensitive=yes ou --case-sensitive=no. As expressões regulares são permitidas, ou seja, a barra vertical funciona como OU.

Seguir o log em tempo real

O -f agarra-se ao fim do journal e mostra as linhas novas assim que elas chegam. Isto só faz sentido, quase sempre, com um filtro; caso contrário passa meio sistema pelo ecrã. O -n define quantas linhas anteriores aparecem primeiro; sem indicação, são dez. Termina-se com Ctrl+C.

journalctl -u nginx.service -f -n 100
journalctl -f -u nginx.service -u php8.2-fpm.service
journalctl -f -p warning

O procedimento habitual para um erro reproduzível: acompanhar a leitura numa primeira sessão e provocar o erro numa segunda. Com linhas muito largas ajuda o -o cat, porque então aparece apenas o texto da mensagem, sem marca temporal nem remetente.

Passo de verificação: se ao provocar o erro não chegar absolutamente nada, o serviço não regista no journal, mas num ficheiro próprio. Nos servidores web e nas bases de dados, esse é o caso normal. Nessa altura, o caminho passa pela configuração da aplicação e não por mais opções do journalctl.

Formatos de saída

O formato predefinido está pensado para pessoas diante do terminal. Para cruzar com outros logs, para pipes e para análises existem formatos mais adequados. A mudança faz-se com -o:

FormatoPara quê
shortPredefinição, hora local ao segundo
short-isoMarca temporal segundo a norma ISO 8601, com desvio de fuso, ideal para cruzar dados
short-precisecomo short, mas com frações de segundo
short-monotonicSegundos desde o arranque do sistema, bom para problemas de arranque
short-unixTempo Unix, bom para cálculos posteriores
catapenas o texto da mensagem, pensado para pipes
verbosetodos os campos de uma entrada, é assim que se aprendem os nomes dos campos
json-prettylegível por máquina e, ainda assim, legível por pessoas
journalctl -u ssh.service -n 1 -o verbose --no-pager

Este único comando vale mais do que qualquer lista de campos num guia: vê quais os campos que as suas entradas realmente trazem e pode usar depois qualquer um deles como filtro. Quatro opções completam o quadro:

  • O --no-pager desliga o pager. Em scripts e antes de qualquer pipe é obrigatório, caso contrário a invocação fica à espera de uma tecla que ninguém carrega.
  • O -r inverte a ordem, as linhas mais recentes ficam no topo.
  • O -e salta imediatamente para o fim dentro do pager.
  • O -x acrescenta, nas mensagens do próprio systemd, um texto explicativo do catálogo.

Com --output-fields= é possível reduzir a saída aos campos que interessam. Isto só produz efeito com verbose, json e formatos aparentados:

journalctl -u ssh.service --since "-1h" -o json --output-fields=MESSAGE,_PID --no-pager

Conservar o journal para lá dos reinícios

Se o journal sobrevive a um reinício, decide-o a predefinição Storage=auto segundo uma regra simples: se /var/log/journal existir, é para lá que se escreve e tudo se mantém. Se não existir, tudo vai parar à memória RAM, em /run/log/journal, e desaparece no reinício seguinte. Não confie na distribuição, porque entre variantes de instalação e imagens de cloud ocorrem os dois estados. Um journal em RAM é a explicação mais frequente para o facto de, depois de um crash, já ninguém conseguir dizer o que se passou antes.

Se fizer a mudança, defina o limite no mesmo passo de trabalho. A experiência mostra que, mais tarde, isso já não acontece:

mkdir -p /etc/systemd/journald.conf.d
cat > /etc/systemd/journald.conf.d/10-kh-journal.conf <<'EOF'
[Journal]
Storage=persistent
SystemMaxUse=500M
SystemKeepFree=1G
MaxRetentionSec=1month
EOF
systemctl restart systemd-journald
journalctl --flush

O Storage=persistent cria o diretório por si próprio, não é preciso qualquer mkdir. O journalctl --flush transfere aquilo que ainda estiver em /run para /var/log/journal.

Passos de verificação, por esta ordem:

systemd-analyze cat-config systemd/journald.conf | grep -v '^#'
ls -d /var/log/journal
journalctl -u systemd-journald -b -n 20 --no-pager

O primeiro comando mostra a configuração efetiva, resultante do ficheiro principal e de todos os ficheiros complementares, ou seja, aquilo que o serviço leu realmente. O terceiro é o teste às gralhas: se ali existir uma linha com Unknown key, a sua definição não está a produzir efeito. Consoante a versão do systemd, ela diz Unknown key name 'SystemMaxUsage' in section 'Journal', ignoring ou Unknown key 'SystemMaxUsage' in section [Journal], ignoring.

A prova final é um reinício a sério. Depois dele, o journalctl --list-boots tem de mostrar pelo menos duas linhas e o journalctl -b -1 -n 20 tem de devolver entradas. Quem preferir criar o diretório à mão segue o caminho abaixo. A invocação de systemd-tmpfiles trata aí de definir o proprietário, as permissões e as listas de acesso que permitem a leitura aos grupos indicados:

mkdir -p /var/log/journal
systemd-tmpfiles --create --prefix /var/log/journal
systemctl restart systemd-journald

Ler sem root

Um utilizador normal vê apenas as suas próprias mensagens e recebe ainda o aviso Hint: You are currently not seeing messages from other users and the system. com a indicação dos grupos que podem ler tudo. No Debian e no Ubuntu, esse grupo é habitualmente o adm:

usermod -aG adm nomedeutilizador

Passo de verificação: a pertença ao grupo só vale num novo início de sessão. Ou seja, terminar a sessão, iniciá-la de novo e depois id -nG e journalctl -n 5. Se o aviso deixar de aparecer e surgirem mensagens do sistema, resultou.

Limitar o tamanho antes que o disco o faça

ChaveEfeito
SystemMaxUseLimite máximo do journal no disco
SystemKeepFreeEspaço em disco que o journal deixa livre
RuntimeMaxUseo mesmo para o journal em RAM, em /run
MaxRetentionSecIdade máxima das entradas, independentemente do tamanho

O /etc/systemd/journald.conf original lista todas as chaves como linhas comentadas com as respetivas predefinições e é, por isso, a fonte mais fiável sobre o que vale neste momento no seu sistema. Depois de cada alteração é preciso um systemctl restart systemd-journald, e a seguir o journalctl --disk-usage mostra o resultado.

Para a medida imediata num disco cheio vale uma ordem em que muita gente tropeça: as opções de limpeza tocam exclusivamente em ficheiros de journal já encerrados, nunca naquele que está ativo. Sem uma rotação prévia, aparentemente não acontece nada, e a saída diz, em substância, Vacuuming done, freed 0B of archived journals.

journalctl --rotate
journalctl --vacuum-time=7d

Mais sobre isto, incluindo os restantes devoradores de espaço, encontra no artigo Disco cheio em Linux.

Uma segunda razão para linhas em falta é o rate limit integrado, através de RateLimitIntervalSec e RateLimitBurst: se um serviço escrever muitíssimas mensagens em pouco tempo, o journald descarta o excedente e assinala-o com uma linha que contém a palavra Suppressed. Se um log tiver lacunas apesar de o serviço estar comprovadamente a correr, procure primeiro por isso:

journalctl -b --grep "Suppressed" --no-pager

Mensagens do kernel: journalctl -k e dmesg

O -k mostra exclusivamente mensagens do kernel e inclui já o -b, ou seja, limita automaticamente a saída ao arranque em curso. Quem procurar a causa depois de um reinício tem de pedir expressamente o arranque anterior:

journalctl -k -p err --no-pager
journalctl -k -b -1 --no-pager

A diferença face ao dmesg está no local de armazenamento. O dmesg lê o buffer circular do kernel: limitado, transborda e fica vazio depois de um reinício. O journal guarda as mesmas mensagens, desde que seja persistente. Para um incidente de ontem, o journalctl -k é, portanto, a única fonte fiável. A isto juntam-se duas notas práticas: o dmesg -T converte em horas os segundos decorridos desde o arranque e engana-se ligeiramente ao fim de longos períodos de funcionamento, ao passo que o journal indica sempre a hora real. E o kernel.dmesg_restrict está a 1 nas quatro distribuições, pelo que uma invocação sem root falha com Operation not permitted.

Porque é que muitos servidores já não têm /var/log/syslog

O journal não é um complemento dos clássicos ficheiros de texto, é o substituto deles. O /var/log/syslog e o /var/log/auth.log não nascem do systemd, mas de um serviço de syslog adicional, habitualmente o rsyslog. Este é um pacote próprio e já não faz parte do que vem instalado nas instalações mínimas de Debian 12 e Debian 13. Nas imagens de servidor do Ubuntu 22.04 e 24.04, está presente.

ls -l /var/log/syslog /var/log/auth.log
systemctl status rsyslog --no-pager

Se não houver nenhum serviço de syslog instalado, o segundo comando responde com Unit rsyslog.service could not be found. Isto explica três observações de uma só vez: os guias com tail -f /var/log/syslog falham com tail: cannot open '/var/log/syslog' for reading: No such file or directory, a procura de tentativas de início de sessão em /var/log/auth.log não dá nada, e o fail2ban tem de ir buscar os seus eventos ao journal. Como isso se configura está no artigo Configurar o fail2ban.

Instalar o rsyslog a posteriori só porque se está habituado a esses ficheiros raramente compensa: passa a guardar tudo em duplicado e precisa ainda de uma regra de logrotate a funcionar. Faz sentido quando os logs devem seguir para um sistema central.

Padrões de pesquisa prontos para a emergência

Um serviço morreu ou está sempre a reiniciar

systemctl list-units --type=service --state=failed --no-pager
journalctl -b -p err --no-pager
journalctl -b --grep "Main process exited|Failed with result|Start request repeated" --no-pager

A terceira linha encontra as mensagens com que o systemd assinala os crashes e o seu travão de arranque integrado. Se um core dump se tornar interessante, é este ficheiro que esclarece primeiro quem é o responsável por ele:

cat /proc/sys/kernel/core_pattern

Se ali estiver uma invocação de systemd-coredump, o coredumpctl list lista os dumps existentes. Se estiver outra coisa qualquer, ou apenas core, o responsável é outro handler e o coredumpctl fica vazio.

Falta de memória

journalctl -k -b --grep "Out of memory|oom-kill" --no-pager
journalctl --since "-7d" --grep "Out of memory|oom-kill" --no-pager
journalctl -u systemd-oomd --since "-7d" --no-pager

O segundo comando dispensa de propósito o -k e procura, assim, para lá dos limites de cada arranque. O terceiro vale para o Ubuntu 22.04 e 24.04, onde o systemd-oomd corre de origem e termina control groups inteiros antes de o kernel intervir; no Debian, este serviço não faz parte do equipamento padrão. Como se distinguem as mensagens está no artigo Configurar swap e evitar Out of Memory.

Inícios de sessão falhados

journalctl -u ssh --since "-24h" --grep "Failed password|Invalid user" --no-pager

Mais interessante do que as linhas isoladas é a distribuição. A linha seguinte conta os endereços de origem e ordena-os por ordem decrescente:

journalctl -u ssh --since "-24h" -g "Failed password" -o cat --no-pager | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head

O truque está em contar a partir do fim: a mensagem termina sempre em from ENDERECO port NUMERO ssh2, ou seja, o quarto campo a contar de trás é o endereço, independentemente de à frente estar um nome de utilizador válido ou inventado e de se tratar de IPv4 ou IPv6. Aqui, o -o cat é obrigatório, porque de outro modo a marca temporal e o remetente deslocam a contagem dos campos. A contraprova para os inícios de sessão bem sucedidos:

journalctl -u ssh --since "-7d" -g "Accepted (publickey|password)" -o cat --no-pager

O que aconteceu às 03:14, e o que veio antes?

journalctl --since "2026-09-02 03:10" --until "2026-09-02 03:20" -o short-iso --no-pager
journalctl -b -1 -n 100 --no-pager
journalctl _PID=1234 --since "-1h" --no-pager

O segundo comando mostra as últimas cem linhas antes do fim anterior. Reconhece um encerramento ordenado pelo facto de o systemd terminar ali serviços em série. Se a saída se interromper a meio do funcionamento normal, foi um crash, um reset forçado ou uma falha de energia. Quanto ao terceiro comando, vale o seguinte: os números de processo são reutilizados, e sem uma janela de tempo pode estar a misturar dois programas diferentes na mesma saída.

Erros frequentes e soluções

No journal files were found.: não existem ficheiros de journal legíveis. Ou o systemd-journald não está a correr, ou não tem acesso enquanto utilizador normal. Verifique primeiro com systemctl is-active systemd-journald e repita depois como root.

-- No entries --: o filtro não encontrou nada. Não é uma mensagem de erro, é uma resposta correta a uma pergunta possivelmente errada. As três causas mais frequentes: um nome de unit que é apenas um nome alternativo, uma janela de tempo demasiado apertada e um -k quando a mensagem procurada nem sequer veio do kernel.

Hint: You are currently not seeing messages from other users and the system.: está a ler como utilizador normal. Peça a inclusão no grupo adm e inicie sessão de novo, ou trabalhe logo com sudo.

No journal boot entry found for the specified boot (-1) ou, conforme o sistema, No journal boot entry found from the specified boot offset (-1): no journal não consta nenhum arranque anterior. É o caso normal enquanto o journal estiver apenas em RAM.

Failed to add match: a expressão não é um filtro de campo válido. Os nomes dos campos escrevem-se em maiúsculas e a comparação é feita sobre o valor completo. Para correspondências parciais no texto da mensagem, o responsável é o --grep.

Unknown key name 'SystemMaxUsage' in section 'Journal', ignoring: uma gralha no ficheiro complementar. O systemd salta a linha e continua a trabalhar com a predefinição. Encontra-se através de journalctl -u systemd-journald -b.

Vacuuming done, freed 0B of archived journals: não havia nada arquivado para apagar, porque é o ficheiro ativo que ocupa o espaço. Primeiro journalctl --rotate, depois limpar outra vez.

Operation not permitted no dmesg: o kernel.dmesg_restrict está a 1. Repita como root ou passe para o journalctl -k.

File /var/log/journal/.../system.journal corrupted or uncleanly shut down, renaming and replacing.: o servidor foi abaixo de forma abrupta enquanto um ficheiro de journal estava aberto. O journald acrescenta um til ao nome antigo e começa um ficheiro novo. O estado de todos os ficheiros verifica-se com journalctl --verify, que devolve uma linha com PASS por cada ficheiro; as queixas dizem respeito, regra geral, exatamente aos ficheiros antigos com o til.

Diferenças entre Debian 13, Debian 12, Ubuntu 24.04 e 22.04

  • Debian 13 (trixie): systemd 257. OpenSSH 10.0, os inícios de sessão ficam sob o identificador sshd-session. O rsyslog não existe nas instalações mínimas, faltando então o /var/log/syslog. O systemd-oomd não faz parte do equipamento padrão.
  • Debian 12 (bookworm): systemd 252. OpenSSH 9.2, tudo sob sshd. O rsyslog existe consoante a variante de instalação, ou seja, o /var/log/syslog não é garantido. O systemd-oomd não faz parte do equipamento padrão.
  • Ubuntu 24.04 LTS: systemd 255. OpenSSH 9.6, tudo sob sshd. O rsyslog está presente. O systemd-oomd está ativo de origem. O SSH corre através de uma ativação por socket, pelo que convém consultar no journal o nome real da unit.
  • Ubuntu 22.04 LTS: systemd 249. OpenSSH 8.9, tudo sob sshd. O rsyslog está presente. O systemd-oomd está ativo de origem. É a mais antiga das quatro versões do systemd, faltando ali alguns formatos de saída mais recentes.

O essencial é igual nos quatro sistemas: os mesmos filtros, as mesmas prioridades, o mesmo ficheiro de configuração e a mesma regra de que é o /var/log/journal que decide a durabilidade.


A ordem que se comprova no dia a dia: primeiro a janela de tempo, depois a unit, depois a prioridade e, por fim, um padrão de pesquisa. Quem proceder assim não precisa de três comandos para a maioria das avarias. E quem tratar uma vez de garantir que o journal sobrevive aos reinícios e mantém, ainda assim, um limite máximo, continua a poder responder à pergunta sobre o porquê muito depois de o servidor já estar a funcionar de novo.

Perguntas frequentes

Como limito o journal ao período da avaria?
Primeiro a janela de tempo, só depois o nome do serviço e a prioridade. O journalctl --since "-30min" devolve a última meia hora, o journalctl --since "2026-09-02 03:10" --until "2026-09-02 03:20" um intervalo fixo, e as formas curtas chamam-se -S e -U. Atenção ao fuso: o journalctl trabalha na hora local do servidor, ao passo que as aplicações registam muitas vezes em UTC. Quem copiar sem pensar uma marca temporal de um log de aplicação procura, no verão, duas horas ao lado do acontecimento. Se a resposta for -- No entries --, alargue a janela para uma hora, a título de teste, antes de duvidar dos filtros.
Porque é que o journalctl -u mysql não devolve linhas, apesar de a base de dados registar?
Porque o -u compara por igualdade e não por semelhança. Num sistema Debian com MariaDB, o mysql.service é apenas um nome alternativo para o mariadb.service, mas o journal guarda tudo sob o nome verdadeiro. Recebe por isso -- No entries -- e nenhuma mensagem de erro, ou seja, uma resposta errada que não tem o aspeto de um erro. O nome verdadeiro obtém-se com journalctl -F _SYSTEMD_UNIT | sort | grep -i sql. A questão também se resolve com padrões, que o -u aceita: journalctl -u "mysql*" -u "mariadb*" -n 60 --no-pager.
Porque é que os inícios de sessão SSH no Debian 13 não aparecem sob journalctl -t sshd?
Desde a versão 9.8, o OpenSSH transfere as sessões para um processo próprio, o sshd-session. No Debian 13 (OpenSSH 10.0), sob -t sshd fica por isso apenas o registo de que o serviço está à escuta, ao passo que cada início de sessão fica sob -t sshd-session. O Debian 12, o Ubuntu 24.04 e o Ubuntu 22.04 não conhecem esta divisão. Quem no Debian 13 filtrar só por -t sshd julga estar perante um servidor calmo, quando na verdade cada tentativa está a ser registada. Mais robusto é o caminho pela unit, porque os processos filhos pertencem à mesma: journalctl -u ssh --since "-24h".
Porque é que o -p err não mostra os erros do meu próprio serviço?
Aquilo que um serviço escreve na saída padrão fica no journal, por predefinição, como info, mesmo que tenha saído pela saída de erro padrão. Um programa que imprime uma exceção com stacktrace aparece assim como uma inofensiva mensagem de funcionamento, e o -p err esconde-a. Só recebem um nível adequado os programas que escrevem diretamente contra a interface do journal ou que antepõem às suas linhas um prefixo syslog. Nos serviços próprios, filtre por isso pela unit e pelo texto; nos serviços de sistema e no kernel, o -p é bem útil.
Como garanto que o journal sobrevive a um reinício?
Com a predefinição Storage=auto, isso decide-se num único diretório: se /var/log/journal existir, tudo se mantém. Se não existir, o journal fica em RAM, em /run/log/journal, e desaparece no reinício seguinte. Crie um ficheiro próprio em /etc/systemd/journald.conf.d/, defina aí Storage=persistent em conjunto com um limite máximo como SystemMaxUse=500M e MaxRetentionSec=1month, reinicie o serviço com systemctl restart systemd-journald e recupere com journalctl --flush aquilo que ainda estiver em /run. A prova é um reinício a sério: depois dele, o journalctl --list-boots tem de mostrar pelo menos duas linhas.
O que significa "No journal boot entry found for the specified boot (-1)"?
No journal não consta nenhum arranque anterior. No Ubuntu 24.04, a mesma afirmação aparece como "No journal boot entry found from the specified boot offset (-1)". Não é uma avaria, é o aviso de que ali não há nada a obter, e é o caso normal enquanto o journal estiver apenas em RAM. Se também o journalctl --list-boots mostrar uma única linha, é provável que nada esteja a ser guardado de forma permanente. Quem quiser analisar de futuro o arranque anterior muda antes para Storage=persistent.
Porque é que o journalctl --vacuum-time não liberta espaço?
As opções de limpeza tocam exclusivamente em ficheiros de journal já encerrados, nunca naquele que está ativo. Sem uma rotação prévia, aparentemente não acontece nada, e a saída diz, em substância, "Vacuuming done, freed 0B of archived journals". A ordem correta é primeiro journalctl --rotate e depois journalctl --vacuum-time=7d. Tenha presente que a operação apaga de forma irreversível, incluindo as provas que anda justamente à procura.
Porque é que o meu servidor Debian não tem /var/log/syslog?
Porque esse ficheiro não nasce do systemd, mas de um serviço de syslog adicional, habitualmente o rsyslog. Este é um pacote próprio e já não faz parte do que vem instalado nas instalações mínimas de Debian 12 e Debian 13; nas imagens de servidor do Ubuntu 22.04 e 24.04, está presente. Se faltar, o systemctl status rsyslog responde com "Unit rsyslog.service could not be found." e o tail -f /var/log/syslog falha com "tail: cannot open '/var/log/syslog' for reading: No such file or directory". As mensagens estão lá na mesma, lê-as com o journalctl, e o fail2ban também vai buscar os seus eventos ao journal.

journalctl systemd Linux Debian Ubuntu Ficheiros de log Resolução de problemas Administração de servidores