Consulta ao journald com journalctl em scripts
Filtre entradas do diário do systemd por unidade, prioridade e horário para fazer a triagem automatizada de incidentes.
Consulta ao journald com journalctl em scripts é uma aula grátis de Linux Command Line & Bash Scripting Mastery no CoddyKit. Esta é a aula 3 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Linux Command Line & Bash Scripting Mastery, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Linux Command Line & Bash Scripting Mastery inclui 4 aulas no total.
Por que usar o journald na triagem de incidentes?
Os sistemas Linux modernos que executam o systemd centralizam toda a saída de registros no diário — um armazenamento estruturado e binário de registros, gerenciado pelo systemd-journald. Diferentemente dos arquivos de texto simples em /var/log, cada entrada do diário contém metadados detalhados: nome da unidade, nível de prioridade, PID, UID, marca de tempo e muito mais.
Em scripts automatizados de triagem de incidentes, esses metadados permitem:
- Filtrar registros de um único serviço sem encadear comandos
grep - Limitar as consultas a intervalos exatos (últimos 15 minutos, desde uma implantação)
- Emitir apenas mensagens críticas/de erro, ignorando ruídos
- Enviar a saída estruturada diretamente para pipelines de alertas
A ferramenta que disponibiliza tudo isso é o journalctl. Nesta lição, você aprenderá a controlá-la programaticamente dentro de scripts Bash.
Invocação básica do journalctl
A forma mais simples de usar o journalctl despeja todo o diário. Em scripts, quase nunca é isso que você deseja — sempre adicione pelo menos um filtro. Estas são as opções mais comuns para encadear:
-u <unit>— filtra por unidade do systemd (por exemplo,nginx.service)-p <priority>— filtra por prioridade do syslog (0=emerg … 7=debug)--since/--until— intervalo de tempo-n <N>— últimas N linhas--no-pager— desativa a paginação interativa (essencial em scripts)-o <format>— formato da saída (short,json,catetc.)
Sempre passe --no-pager em scripts não interativos para que o journalctl não tente iniciar o less e fique travado.
#!/usr/bin/env bash
# Print the last 20 lines of the nginx service journal
journalctl --no-pager -u nginx.service -n 20Filtrando por unidade do Systemd
A opção -u aceita qualquer nome de unidade válido. Você pode fornecê-la várias vezes para combinar unidades, o que é útil quando uma única aplicação abrange vários serviços (por exemplo, uma API e seu serviço auxiliar de banco de dados).
Os nomes de unidades seguem o padrão <name>.service, <name>.socket, <name>.timer etc. O uso de curingas é aceito: -u 'myapp*' corresponde a myapp-api.service, myapp-worker.service e assim por diante.
Em um script de triagem, normalmente você recebe o nome da unidade como argumento, tornando o filtro dinâmico.
#!/usr/bin/env bash
# Usage: ./unit_logs.sh nginx.service
UNIT="${1:?Usage: $0 <unit>}"
echo "=== Journal for ${UNIT} (last 50 lines) ==="
journalctl --no-pager -u "${UNIT}" -n 50
# Combine two related units
echo "=== Combined: api + worker ==="
journalctl --no-pager -u myapp-api.service -u myapp-worker.service -n 30Níveis de prioridade e a opção -p
A opção -p corresponde aos níveis de prioridade padrão do syslog:
0— emerg1— alert2— crit3— err4— warning5— notice6— info7— debug
Você pode especificar um único nível (-p err) para ver somente esse nível ou um intervalo (-p emerg..err) para capturar tudo, desde emergências até erros — a opção mais comum para alertas automatizados.
Apelidos nomeados (err, warning, crit) são aceitos juntamente com valores numéricos.
#!/usr/bin/env bash
# Extract only error-level and above entries for sshd
journalctl --no-pager \
-u sshd.service \
-p emerg..err \
--since "1 hour ago"
# Exit non-zero if any errors were found (useful in CI health checks)
ERROR_COUNT=$(journalctl --no-pager -u sshd.service -p emerg..err \
--since "1 hour ago" --output=cat | wc -l)
if [[ "${ERROR_COUNT}" -gt 0 ]]; then
echo "[ALERT] ${ERROR_COUNT} error(s) detected in sshd" >&2
exit 1
fiFiltragem por intervalo de tempo com --since e --until
Os filtros de tempo são a base das consultas sobre janelas de incidentes. O journalctl aceita marcas de data e hora flexíveis e legíveis:
- Relativas:
"10 minutes ago","2 hours ago","yesterday" - Absoluta:
"2026-06-11 14:00:00" - Palavras-chave especiais:
today,yesterday,-1h(forma abreviada)
Em scripts de implantação, um padrão comum é capturar a marca de data e hora imediatamente antes de uma implantação e, em seguida, consultar o diário a partir desse ponto para detectar regressões introduzidas pela versão.
#!/usr/bin/env bash
# Record deploy start time, then check logs afterwards
DEPLOY_START=$(date +"%Y-%m-%d %H:%M:%S")
echo "Deploying at ${DEPLOY_START}..."
# ... your deploy steps here ...
sleep 2 # simulate deploy
echo "=== Journal since deploy start ==="
journalctl --no-pager \
-u myapp.service \
--since "${DEPLOY_START}" \
-p emerg..warningSaída estruturada no formato JSON
Para pipelines legíveis por máquinas, passe -o json (um objeto JSON por linha, NDJSON) ou -o json-pretty (formatado). Cada objeto contém todos os campos do diário:
MESSAGE— o texto do registroPRIORITY— prioridade numérica (0–7)_SYSTEMD_UNIT— unidade de origem__REALTIME_TIMESTAMP— microssegundos desde a época Unix_PID,_UID,_HOSTNAME— metadados do processo
Você pode encaminhar esse fluxo NDJSON para jq a fim de extrair, filtrar ou reformataar campos para sistemas de alertas posteriores, como PagerDuty, webhooks do Slack ou coletores de SIEM.
#!/usr/bin/env bash
# Extract error messages as a clean list for a Slack notification
MESSAGES=$(journalctl --no-pager \
-u nginx.service \
-p emerg..err \
--since "30 minutes ago" \
-o json \
| jq -r '.MESSAGE' \
| sort -u)
if [[ -n "${MESSAGES}" ]]; then
echo "Errors detected:"
echo "${MESSAGES}"
fiAcompanhar o diário em tempo real
A opção -f faz o journalctl acompanhar o diário ao vivo — de modo análogo a tail -f em um arquivo de registro. Combinada com filtros de unidade e prioridade, ela se torna um monitor direcionado em tempo real.
Em pipelines com scripts, o padrão mais útil é a consulta baseada em cursor: salve o cursor atual do diário e, a cada consulta, passe --after-cursor=<cursor> para ler somente as novas entradas desde a última verificação. Isso evita processar novamente linhas antigas.
Recupere o cursor mais recente com --show-cursor -n 0 e analise a linha -- cursor: da saída.
#!/usr/bin/env bash
# Cursor-based polling: read only new journal entries each run
CURSOR_FILE="/tmp/triage_cursor"
if [[ -f "${CURSOR_FILE}" ]]; then
CURSOR=$(cat "${CURSOR_FILE}")
NEW_ENTRIES=$(journalctl --no-pager \
-u myapp.service \
-p emerg..err \
--after-cursor="${CURSOR}" \
-o json)
else
# First run: look back 5 minutes
NEW_ENTRIES=$(journalctl --no-pager \
-u myapp.service \
-p emerg..err \
--since "5 minutes ago" \
-o json)
fi
# Save updated cursor for next poll
journalctl --no-pager -n 0 --show-cursor 2>&1 \
| grep '^-- cursor:' \
| sed 's/-- cursor: //' \
> "${CURSOR_FILE}"
echo "${NEW_ENTRIES}" | jq -r '.MESSAGE // empty'Consultas restritas à inicialização com -b
A opção -b restringe uma consulta a uma sessão de inicialização específica. Isso é essencial após uma falha ou reinicialização inesperada, para recuperar os registros da inicialização anterior em vez da atual.
-b 0— inicialização atual (padrão)-b -1— inicialização anterior-b -2— duas inicializações atrás--list-boots— mostra todas as sessões de inicialização registradas com suas marcas de data e hora
Scripts de análise pós-incidente geralmente extraem os registros críticos da inicialização anterior (-b -1) para diagnosticar por que o sistema falhou ou por que um serviço não iniciou corretamente.
#!/usr/bin/env bash
# Post-mortem: collect critical logs from the previous boot
echo "=== Previous boot sessions ==="
journalctl --list-boots
echo ""
echo "=== Critical entries from previous boot ==="
journalctl --no-pager \
-b -1 \
-p emerg..crit \
-o short-isoUso de grep no journalctl versus correspondências nativas
Você pode passar um padrão bruto de grep após todas as opções, mas o journalctl também oferece correspondências nativas de campos usando a sintaxe FIELD=value. As correspondências nativas são avaliadas em relação aos metadados estruturados — muito mais rapidamente que o pós-processamento de texto com grep.
Correspondências úteis comuns:
_PID=1234— registros de um processo específico_COMM=python3— registros de qualquer processo chamadopython3SYSLOG_IDENTIFIER=myapp— registros marcados com um identificador personalizado
Vários argumentos FIELD=value são combinados com AND; um + entre eles cria um OR. Use -g <regex> para uma busca textual completa com grep quando os metadados estruturados não forem suficientes.
#!/usr/bin/env bash
# Native field match: errors from the postgres process only
journalctl --no-pager \
_COMM=postgres \
-p emerg..err \
--since "1 hour ago"
# Full-text grep for a specific error string
journalctl --no-pager \
-u postgresql.service \
--since "1 hour ago" \
-g "FATAL|PANIC" \
--output=catCriando uma função reutilizável de triagem
Depois que você dominar as opções individuais, compô-las em uma função Bash reutilizável mantém seus scripts de triagem limpos e consistentes. Uma função bem projetada deve:
- Aceitar unidade, intervalo de prioridades e janela de tempo como parâmetros
- Usar valores seguros e com pouco ruído quando os argumentos forem omitidos
- Retornar um código de saída diferente de zero quando forem encontrados erros (integrando-se a pipelines de CI)
- Gravar as descobertas tanto na saída padrão quanto em um arquivo de registro com marca de data e hora para fins de auditoria
#!/usr/bin/env bash
# triage.sh — reusable journal triage function
triage_unit() {
local unit="${1:?unit required}"
local priority="${2:-emerg..err}"
local since="${3:-1 hour ago}"
local logfile="/tmp/triage_${unit//[^a-zA-Z0-9]/_}_$(date +%s).log"
echo "[$(date -Iseconds)] Triaging ${unit} | prio=${priority} | since='${since}'" | tee "${logfile}"
journalctl --no-pager \
-u "${unit}" \
-p "${priority}" \
--since "${since}" \
-o short-iso \
| tee -a "${logfile}"
local count
count=$(wc -l < "${logfile}")
# Subtract 1 for the header line
(( count-- ))
if [[ "${count}" -gt 0 ]]; then
echo "[ALERT] ${count} line(s) logged to ${logfile}" >&2
return 1
fi
return 0
}
# Example: triage nginx errors in the last 30 minutes
triage_unit nginx.service "emerg..err" "30 minutes ago"Script automatizado de triagem de incidentes
O script completo a seguir reúne todos os conceitos em uma ferramenta prática de triagem automatizada. Ele lê uma lista de serviços críticos, consulta o diário para cada um deles durante uma janela de retrospectiva configurável, agrega as descobertas e termina com um código de falha se algum erro for detectado — o que o torna adequado para uma tarefa do cron ou uma etapa de verificação de integridade da CI.
#!/usr/bin/env bash
# incident_triage.sh — automated multi-service journal triage
set -euo pipefail
LOOKBACK="${1:-15 minutes ago}"
PRIORITY="emerg..err"
SERVICES=(nginx.service postgresql.service myapp-api.service myapp-worker.service)
REPORT="/tmp/incident_report_$(date +%Y%m%d_%H%M%S).txt"
FAILED=0
{
echo "Incident Triage Report"
echo "Generated : $(date -Iseconds)"
echo "Lookback : ${LOOKBACK}"
echo "Priority : ${PRIORITY}"
echo "-----------------------------------"
} > "${REPORT}"
for svc in "${SERVICES[@]}"; do
ENTRIES=$(journalctl --no-pager \
-u "${svc}" \
-p "${PRIORITY}" \
--since "${LOOKBACK}" \
--output=cat 2>/dev/null || true)
COUNT=$(echo "${ENTRIES}" | grep -c . || true)
if [[ "${COUNT}" -gt 0 ]]; then
echo "[FAIL] ${svc}: ${COUNT} error(s)" | tee -a "${REPORT}"
echo "${ENTRIES}" >> "${REPORT}"
echo "-----------------------------------" >> "${REPORT}"
FAILED=1
else
echo "[OK] ${svc}"
fi
done
echo ""
echo "Full report: ${REPORT}"
exit "${FAILED}"Verificação de conhecimento: filtragem por intervalo de prioridades
Você está escrevendo um script para alertar os engenheiros de plantão somente quando um serviço registrar mensagens com gravidade de erro ou superior (ou seja, erro, crítico, alerta ou emergência). Qual combinação de opções do journalctl captura exatamente esse intervalo?
Recapitulação da lição: journalctl em scripts
Nesta lição, você aprendeu a consultar programaticamente o diário do systemd para realizar a triagem automatizada de incidentes:
- Sempre passe
--no-pagernos scripts para evitar bloqueios interativos. - Filtragem por unidade (
-u) restringe as consultas a um ou mais serviços; são aceitos curingas e várias opções-u. - Filtragem por prioridade (
-p emerg..err) captura somente os níveis de gravidade relevantes — lembre-se de que números menores indicam maior gravidade. - Janelas de tempo (
--since/--until) isolam a saída de registros em uma janela de implantação ou em um período de retrospectiva usando marcas de data e hora legíveis. - Restrição por inicialização (
-b -1) permite que scripts pós-incidente leiam registros de uma sessão de falha anterior. - Saída JSON (
-o json) ejqpermitem pipelines estruturados que alimentam sistemas de alertas ou de SIEM. - Consultas baseadas em cursor com
--after-cursorevitam processar novamente entradas antigas em execuções repetidas. - Correspondências nativas de campos (
_COMM=,SYSLOG_IDENTIFIER=) são mais rápidas que encaminhar a saída paragrep.
Combinar essas opções em uma função Bash reutilizável fornece uma ferramenta de triagem pronta para produção, que se integra facilmente ao cron, a pipelines de CI e a fluxos de alertas para a equipe de plantão.
Perguntas Frequentes
A aula “Consulta ao journald com journalctl em scripts” é grátis?
Sim — o texto completo de “Consulta ao journald com journalctl em scripts” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Linux Command Line & Bash Scripting Mastery, atualize para CoddyKit PRO. O curso de Linux Command Line & Bash Scripting Mastery inclui 4 aulas no total.
O que vou aprender em “Consulta ao journald com journalctl em scripts”?
Filtre entradas do diário do systemd por unidade, prioridade e horário para fazer a triagem automatizada de incidentes. Você pratica Linux Command Line & Bash Scripting Mastery com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Linux Command Line & Bash Scripting Mastery?
Nenhuma experiência prévia é necessária. Linux Command Line & Bash Scripting Mastery no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 3 de 4.
Quanto tempo leva a aula “Consulta ao journald com journalctl em scripts”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Linux Command Line & Bash Scripting Mastery?
Sim. Cada aula de Linux Command Line & Bash Scripting Mastery inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Análise de registros da Web e de aplicações em grande escala
- Acompanhamento de registros em tempo real e alertas por transmissão
- Consulta ao journald com journalctl em scripts
- Cálculo de métricas e histogramas a partir de fluxos de registros