Resolução de Problemas em Serviços Linux com systemctl e journalctl
Um fluxo de trabalho prático para depurar serviços Linux com falha ou não saudáveis usando systemctl e journalctl.
Resolução de Problemas em Serviços Linux com systemctl e journalctl
Quando um serviço Linux falha, o caminho mais rápido geralmente não é uma pesquisa na web. São três verificações locais: o que o systemd acha que aconteceu, o que o serviço registrou e o que mudou antes da falha. systemctl e journalctl fornecem essas respostas sem adivinhação.
Este guia usa falhas comuns de serviço como exemplos: um serviço que não inicia, um processo que está em execução mas não está fazendo trabalho útil e um serviço que sai depois de parecer saudável. Os comandos se aplicam à maioria dos serviços gerenciados pelo systemd, mas os nomes exatos das unidades e locais de log variam conforme a distribuição e o pacote.
Entendendo systemctl e journalctl
Antes de mergulhar na resolução de problemas, é crucial entender as funções dessas duas ferramentas principais:
systemctl: Este comando é o utilitário central para controlar e consultar o gerenciador de sistema e serviçossystemd. Ele permite iniciar, parar, reiniciar, verificar o status e ativar/desativar serviços.journalctl: Este comando é usado para consultar o journal do systemd, que é um sistema de log centralizado. Ele coleta logs do kernel, serviços do sistema e aplicativos, fornecendo uma visão unificada dos eventos do sistema.journalctlé inestimável para entender por que um serviço falhou ou se comportou inesperadamente.
Cenários Comuns de Resolução de Problemas e Soluções
Vamos explorar problemas típicos e como resolvê-los:
1. Serviço Falhou ao Iniciar
Este é talvez o problema mais comum. Você tenta iniciar um serviço e ele falha imediatamente.
Passo 1: Verificar o Status do Serviço
Use systemctl status para obter uma visão geral imediata do estado do serviço e das entradas de log recentes.
sudo systemctl status apache2.service
Saída Esperada (Ilustrativa - a sua pode variar):
● apache2.service - The Apache HTTP Server
Loaded: loaded (/lib/systemd/system/apache2.service; enabled; vendor preset: enabled)
Active: **failed** (result: exit-code) since Tue 2023-10-27 10:00:00 UTC; 1min ago
Docs: https://httpd.apache.org/docs/2.4/
Process: 12345 ExecStart=/usr/sbin/apachectl start (code=exited, status=1/FAILURE)
Main PID: 12345 (code=exited, status=1/FAILURE)
Oct 27 10:00:00 your-server systemd[1]: Starting The Apache HTTP Server...
Oct 27 10:00:00 your-server apachectl[12345]: AH00526: Syntax error on line 123 of /etc/apache2/apache2.conf:
Oct 27 10:00:00 your-server apachectl[12345]: Invalid Mutex directory in argument file: '/var/run/apache2/'
Oct 27 10:00:00 your-server systemd[1]: apache2.service: Main process exited, code=exited, status=1/FAILURE
Oct 27 10:00:00 your-server systemd[1]: **Failed** to start The Apache HTTP Server.
Oct 27 10:00:00 your-server systemd[1]: apache2.service: Unit entered failed state.
Análise: A saída de systemctl status mostra claramente Active: failed e fornece um trecho da mensagem de erro: Invalid Mutex directory in argument file: '/var/run/apache2/'. Isso sugere um problema de configuração.
Passo 2: Investigar Logs com journalctl
Para informações mais detalhadas, use journalctl para visualizar logs especificamente para o serviço com falha. A flag -u especifica a unidade (serviço).
sudo journalctl -u apache2.service -xe
-u apache2.service: Filtra logs para a unidadeapache2.service.-x: Adiciona explicações para algumas mensagens de log.-e: Pula para o final do journal, mostrando as entradas mais recentes.
Possíveis Descobertas: A saída do journalctl pode revelar mais contexto sobre o erro de configuração, problemas de permissão ou problemas de dependência.
Passo 3: Verificar Arquivos de Configuração
Com base na mensagem de erro, examine os arquivos de configuração relevantes. No exemplo acima, ele aponta para /etc/apache2/apache2.conf e o diretório /var/run/apache2/.
sudo nano /etc/apache2/apache2.conf
Solução: Problemas como este geralmente vêm de um diretório de tempo de execução ausente, uma alteração de pacote ou um arquivo de configuração que referencia um caminho que não existe mais. Não crie diretórios cegamente a partir de um exemplo na internet. Primeiro confirme o que o aplicativo espera em sua distribuição, depois corrija o caminho ou configuração ausente. Um reparo possível pode ser assim:
sudo mkdir -p /var/run/apache2/
sudo chown www-data:www-data /var/run/apache2/
sudo systemctl start apache2.service
Se o erro mencionar um problema de sintaxe, execute o teste de configuração do próprio aplicativo antes de reiniciar novamente:
sudo apachectl configtest
sudo nginx -t
sudo sshd -t
Validadores específicos do aplicativo capturam erros que o systemd não consegue entender. O systemd sabe se o processo foi encerrado. Ele não sabe se o bloco server do seu Nginx aponta para o arquivo de certificado errado ou se uma diretiva do Apache pertence a um contexto diferente.
2. Serviço está em Execução mas Não Responde
Às vezes, systemctl status mostra um serviço como active (running), mas ele não está executando sua função pretendida (por exemplo, um servidor web não está servindo páginas).
Passo 1: Verificar Status do Serviço e PID
Confirme se ele está realmente em execução e tem um ID de Processo (PID).
sudo systemctl status nginx.service
Se mostrar active (running), anote o PID.
Passo 2: Examinar Logs do Serviço em Busca de Erros
Mesmo em execução, o serviço pode estar encontrando erros internos que o impedem de funcionar corretamente.
sudo journalctl -u nginx.service -f
-f: Segue a saída do log em tempo real. Isso é útil se você puder acionar o problema (por exemplo, tentar acessar a página web) enquanto ojournalctlestá em execução.
Passo 3: Verificar Logs Específicos do Aplicativo
Muitos serviços escrevem seus próprios logs além do journal do systemd. Para servidores web como Nginx ou Apache, verifique seus locais de log típicos (por exemplo, /var/log/nginx/error.log, /var/log/apache2/error.log).
sudo tail -n 50 /var/log/nginx/error.log
Passo 4: Verificar Utilização de Recursos
Um sistema sobrecarregado pode fazer com que os serviços se tornem não responsivos.
top
htop
free -h
Procure por alto uso de CPU, memória ou I/O de disco pelos processos do serviço.
Verifique também se o serviço está ouvindo onde você espera:
sudo ss -ltnp
sudo ss -lunp
Para um serviço web, ver nginx ativo no systemctl é apenas metade da história. Você ainda precisa saber se ele está vinculado a 0.0.0.0:80, 127.0.0.1:8080, um socket IPv6 ou nenhum socket. Uma regra de firewall, incompatibilidade de proxy reverso ou endereço de bind incorreto podem fazer um processo saudável parecer quebrado do lado de fora.
Solução: Se os logs indicarem problemas ou os recursos estiverem sobrecarregados, você pode precisar:
- Otimizar configurações.
- Reiniciar o serviço (
sudo systemctl restart <nome_do_serviço>.service). - Investigar problemas subjacentes de recursos do sistema.
- Aumentar os recursos do sistema, se necessário.
3. Serviço Para Inesperadamente
Se um serviço que estava em execução anteriormente para de repente, geralmente é devido a uma exceção não tratada ou um timeout do watchdog.
Passo 1: Verificar Histórico Recente com journalctl
Use journalctl para ver o que aconteceu pouco antes do serviço parar. As flags --since e --until podem ser úteis se você souber o horário aproximado.
sudo journalctl -u <nome_do_serviço>.service --since "1 hour ago"
Ou, para ver todos os logs relacionados ao serviço desde a última inicialização:
sudo journalctl -u <nome_do_serviço>.service -b
Passo 2: Procurar por Core Dumps ou Relatórios de Crash
Se o serviço travou, o sistema pode ter gerado um core dump ou um relatório de crash.
ls -l /var/crash/
Passo 3: Revisar o Arquivo de Unidade do Serviço systemd
Examine o arquivo de unidade do serviço (geralmente em /etc/systemd/system/ ou /lib/systemd/system/) em busca de diretivas Restart= e configurações WatchdogSec=. Uma configuração Restart= incorreta ou um WatchdogSec= muito curto pode causar reinicializações ou falhas inesperadas.
systemctl cat <nome_do_serviço>.service
Solução: Resolva a causa raiz identificada nos logs. Isso pode envolver corrigir bugs de código, ajustar parâmetros do arquivo de unidade do systemd ou aumentar os limites de recursos.
Se você vir reinicializações repetidas, verifique se o systemd limitou a taxa da unidade:
systemctl status <nome_do_serviço>.service
journalctl -u <nome_do_serviço>.service --since "30 minutes ago"
Mensagens sobre Start request repeated too quickly geralmente significam que o serviço travou várias vezes em um curto período. Após corrigir o problema subjacente, limpe o estado de falha:
sudo systemctl reset-failed <nome_do_serviço>.service
sudo systemctl start <nome_do_serviço>.service
4. Problemas com systemctl enable ou systemctl disable
Embora não seja uma falha em tempo de execução, problemas ao ativar ou desativar serviços podem ocorrer.
Problema: Um serviço está ativado mas não inicia na inicialização, ou vice-versa.
Verificar Status:
sudo systemctl is-enabled <nome_do_serviço>.service
Este comando irá gerar enabled ou disabled.
Resolução de Problemas:
- Certifique-se de que o arquivo de unidade do serviço em si é válido e está colocado corretamente (por exemplo,
/etc/systemd/system/). - Após fazer alterações em um arquivo de unidade, sempre execute
sudo systemctl daemon-reload. - Verifique os logs do serviço (
journalctl -u <nome_do_serviço>.service) em busca de erros de inicialização que possam impedi-lo de se tornar ativo mesmo se estiver ativado.
Dicas para Resolução Eficaz de Problemas
- Comece com
systemctl status: Sempre comece aqui. Ele fornece um instantâneo rápido e muitas vezes aponta na direção certa. - Use
journalctl -u <serviço>: Esta é sua ferramenta principal para entender por que algo está acontecendo. - Flag
-fcomjournalctl: Extremamente útil para monitoramento em tempo real ao tentar reproduzir um problema. systemctl restart <serviço>: Após fazer alterações de configuração, sempre reinicie o serviço para aplicá-las.systemctl daemon-reload: Crucial após modificar quaisquer arquivos de unidade.service.- Verificar Dependências: Às vezes um serviço falha porque um serviço do qual depende não iniciou ou está falhando.
systemctl statusgeralmente mostrará isso. - Permissões: Muitas falhas de serviço são devidas a permissões incorretas de arquivos ou diretórios. Certifique-se de que o usuário sob o qual o serviço é executado tenha o acesso necessário.
- Problemas de Rede: Se o serviço depende da rede, verifique a conectividade de rede, regras de firewall e disponibilidade de porta.
Uma Ordem de Resolução de Problemas que se Sustenta
Quando a pressão está alta, use a mesma ordem todas as vezes:
systemctl status <serviço>.service
journalctl -u <serviço>.service -b --no-pager
systemctl cat <serviço>.service
systemctl list-dependencies <serviço>.service
Comece com o estado atual, depois leia os logs da inicialização atual, depois inspecione a unidade exatamente como o systemd a vê, depois verifique as dependências. Se o serviço for voltado para rede, adicione ss -ltnp e um teste local com curl ou cliente. Se ele lê um arquivo de configuração, execute o validador de configuração do próprio serviço.
O objetivo é evitar reinicializações aleatórias. Reiniciar pode ser uma correção válida após uma alteração de configuração ou um processo travado, mas também destrói evidências. Leia o suficiente do journal primeiro para saber o que você está mudando e por quê.
Lendo a Saída do Journal Sem se Perder
journalctl pode ser barulhento, especialmente em servidores ocupados. Comece estreito, depois amplie apenas quando necessário.
Para um serviço na inicialização atual:
journalctl -u <serviço>.service -b --no-pager
Para os últimos minutos:
journalctl -u <serviço>.service --since "15 minutes ago" --no-pager
Para a inicialização anterior:
journalctl -u <serviço>.service -b -1 --no-pager
Essa visão da inicialização anterior é útil quando um serviço falhou durante a inicialização e depois se recuperou, ou quando a máquina inteira reiniciou antes que você pudesse inspecioná-la. Você pode listar as inicializações com:
journalctl --list-boots
Se o serviço registrar campos estruturados ou linhas longas, use timestamps ISO curtos:
journalctl -u <serviço>.service -o short-iso --no-pager
Quando precisar compartilhar logs, remova segredos, tokens, nomes de host internos e dados do cliente. Os logs de serviço geralmente incluem configurações derivadas do ambiente, URLs, cabeçalhos ou strings de conexão. Um hábito limpo de resolução de problemas inclui a redação antes de colar a saída em qualquer lugar.
Quando o systemctl Diz "Active" mas os Usuários Ainda Veem Falha
Um estado active (running) significa apenas que o systemd tem um processo que corresponde às expectativas da unidade. Não prova que o aplicativo está saudável. Um aplicativo web pode estar em execução enquanto retorna HTTP 500. Um worker pode estar ativo enquanto está travado em uma mensagem de fila ruim. Um proxy de banco de dados pode estar em execução enquanto todas as conexões de backend falham.
Para serviços de rede, teste das mesmas camadas das quais seus usuários dependem:
curl -v http://127.0.0.1:8080/health
curl -v http://localhost/health
curl -v https://service.example.com/health
Essas três verificações respondem a perguntas diferentes. A primeira verifica a porta local do aplicativo. A segunda pode incluir um proxy reverso local. A terceira verifica DNS, TLS, roteamento, regras de firewall e o caminho voltado para o público.
Para serviços worker, observe o que eles consomem ou produzem. Um worker de fila pode precisar de uma verificação de profundidade da fila. Um serviço de backup pode precisar de um arquivo de saída recente. Um coletor de métricas pode precisar de uma consulta ao backend de métricas. systemctl informa se a supervisão está funcionando; as verificações do aplicativo informam se o serviço é útil.
Corrija uma Variável de Cada Vez
Quando uma unidade falha após uma implantação, é tentador mudar várias coisas e reiniciar. Isso pode esconder a causa real. Prefira uma mudança de cada vez:
systemctl cat my-app.service
journalctl -u my-app.service --since "30 minutes ago" --no-pager
sudo systemctl edit my-app.service
sudo systemctl daemon-reload
sudo systemctl restart my-app.service
Em seguida, verifique o resultado antes de mudar a próxima coisa. Se a falha for um arquivo ausente, corrija o caminho do arquivo. Se for um erro de permissão, corrija a propriedade ou modo. Se for uma dependência, corrija o relacionamento da unidade ou o comportamento de repetição do aplicativo. Uma resolução de problemas lenta e metódica é muitas vezes mais rápida do que um loop de reinicialização com cinco edições não rastreadas.