0Pricing
Linux Command Line & Bash Scripting Mastery · Lección

Consulta de journald con journalctl en scripts

Filtre entradas del journal de systemd por unit, prioridad y hora para automatizar la clasificación inicial de incidentes.

Consulta de journald con journalctl en scripts es una lección gratuita de Linux Command Line & Bash Scripting Mastery en CoddyKit. Esta es la lección 3 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Linux Command Line & Bash Scripting Mastery, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Linux Command Line & Bash Scripting Mastery incluye 4 lecciones en total.

¿Por qué journald para la clasificación inicial de incidentes?

Los sistemas Linux modernos que ejecutan systemd centralizan toda la salida de registros en el journal, un almacén de registros binario y estructurado gestionado por systemd-journald. A diferencia de los archivos de texto sin formato de /var/log, cada entrada del journal contiene metadatos detallados: nombre de la unidad, nivel de prioridad, PID, UID, marca de tiempo y más.

En los scripts automatizados de clasificación inicial de incidentes, estos metadatos le permiten:

  • Filtrar los registros de un único servicio sin encadenar comandos grep
  • Limitar las consultas a intervalos de tiempo exactos (los últimos 15 minutos, desde un despliegue)
  • Emitir únicamente mensajes críticos o de error, ignorando el ruido
  • Enviar directamente una salida estructurada a las canalizaciones de alertas

La herramienta que expone toda esta información es journalctl. En esta lección aprenderá a utilizarla mediante programación dentro de scripts de Bash.

Invocación básica de journalctl

La forma más sencilla de journalctl vuelca todo el journal. En los scripts, casi nunca querrá hacer eso; añada siempre al menos un filtro. Estas son las opciones más comunes que puede encadenar:

  • -u <unit> — filtrar por unidad de systemd (por ejemplo, nginx.service)
  • -p <priority> — filtrar por prioridad de syslog (0=emerg … 7=debug)
  • --since / --until — intervalo de tiempo
  • -n <N> — últimas N líneas
  • --no-pager — desactivar la paginación interactiva (esencial en scripts)
  • -o <format> — formato de salida (short, json, cat, etc.)

Pase siempre --no-pager en scripts no interactivos para que journalctl no intente invocar less y se quede bloqueado.

#!/usr/bin/env bash
# Print the last 20 lines of the nginx service journal
journalctl --no-pager -u nginx.service -n 20

Filtrar por unidad de systemd

La opción -u acepta cualquier nombre de unidad válido. Puede proporcionarla varias veces para combinar unidades, lo que resulta útil cuando una aplicación abarca varios servicios (por ejemplo, una API y su sidecar de base de datos).

Los nombres de unidad siguen el patrón <name>.service, <name>.socket, <name>.timer, etc. Se admite el uso de comodines: -u 'myapp*' coincide con myapp-api.service, myapp-worker.service y otros nombres similares.

En un script de clasificación inicial de incidentes, normalmente recibe el nombre de la unidad como argumento, lo que permite que el filtro sea 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 30

Niveles de prioridad y la opción -p

La opción -p se asigna a los niveles de prioridad estándar de syslog:

  • 0 — emerg
  • 1 — alert
  • 2 — crit
  • 3 — err
  • 4 — warning
  • 5 — notice
  • 6 — info
  • 7 — debug

Puede especificar un único nivel (-p err) para ver solo ese nivel, o un intervalo (-p emerg..err) para capturar todo, desde las emergencias hasta los errores — la opción más habitual para las alertas automatizadas.

Se aceptan alias con nombre (err, warning, crit) además de 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
fi

Filtrado por intervalo de tiempo con --since y --until

Los filtros de tiempo son la base de las consultas por ventana de incidentes. journalctl acepta marcas de tiempo flexibles y legibles:

  • Relativas: "10 minutes ago", "2 hours ago", "yesterday"
  • Absoluta: "2026-06-11 14:00:00"
  • Palabras clave especiales: today, yesterday, -1h (forma abreviada)

En los scripts de despliegue, un patrón habitual consiste en capturar la marca de tiempo justo antes de un despliegue y consultar el journal desde ese momento para detectar regresiones introducidas por la versión publicada.

#!/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..warning

Salida estructurada en formato JSON

Para canalizaciones legibles por máquinas, pase -o json (un objeto JSON por línea, NDJSON) o -o json-pretty (formateado). Cada objeto contiene todos los campos del journal:

  • MESSAGE — el texto del registro
  • PRIORITY — prioridad numérica (0–7)
  • _SYSTEMD_UNIT — unidad de origen
  • __REALTIME_TIMESTAMP — microsegundos desde la época Unix
  • _PID, _UID, _HOSTNAME — metadatos del proceso

Puede canalizar este flujo NDJSON a jq para extraer, filtrar o reformatear campos destinados a sistemas de alertas posteriores, como PagerDuty, webhooks de Slack o ingestas 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}"
fi

Seguir el journal en tiempo real

La opción -f hace que journalctl siga el journal en directo, de forma análoga a tail -f aplicado a un archivo de registro. Al combinarla con filtros de unidad y prioridad, se obtiene un monitor en tiempo real y dirigido.

En las canalizaciones con scripts, el patrón más útil es la consulta basada en cursores: guarde el cursor actual del journal y, en cada consulta, pase --after-cursor=<cursor> para leer solo las entradas nuevas desde la última comprobación. Así se evita volver a procesar líneas antiguas.

Recupere el cursor más reciente con --show-cursor -n 0 y analice la línea -- cursor: de la salida.

#!/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 limitadas al arranque con -b

La opción -b limita una consulta a una sesión de arranque específica. Es fundamental después de un bloqueo o reinicio inesperado, ya que permite recuperar los registros del arranque anterior en lugar de los del actual.

  • -b 0 — arranque actual (predeterminado)
  • -b -1 — arranque anterior
  • -b -2 — dos arranques atrás
  • --list-boots — muestra todas las sesiones de arranque registradas con sus marcas de tiempo

Los scripts de análisis post mortem suelen volcar los registros críticos del arranque anterior (-b -1) para diagnosticar por qué se bloqueó el sistema o por qué un servicio falló al iniciarse.

#!/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-iso

Uso de grep dentro de journalctl frente a coincidencias nativas

Puede pasar un patrón de grep sin modificar después de todas las opciones, pero journalctl también admite coincidencias nativas de campos mediante la sintaxis FIELD=value. Las coincidencias nativas se evalúan sobre metadatos estructurados y son mucho más rápidas que procesar posteriormente el texto con grep.

Algunas coincidencias habituales:

  • _PID=1234 — registros de un proceso específico
  • _COMM=python3 — registros de cualquier proceso llamado python3
  • SYSLOG_IDENTIFIER=myapp — registros etiquetados con un identificador personalizado

Varios argumentos FIELD=value se combinan mediante AND; un + entre ellos crea una condición OR. Use -g <regex> para realizar búsquedas de texto completo con grep cuando los metadatos estructurados no sean 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=cat

Crear una función reutilizable de triaje

Una vez que domine las opciones individuales, combinarlas en una función reutilizable de Bash mantiene sus scripts de triaje limpios y coherentes. Una función bien diseñada debería:

  • Aceptar como parámetros la unidad, el intervalo de prioridades y la ventana temporal
  • Usar valores predeterminados seguros y con poco ruido cuando se omitan argumentos
  • Devolver un código de salida distinto de cero cuando se encuentren errores (para integrarse con canalizaciones de CI)
  • Escribir los hallazgos tanto en stdout como en un archivo de registro con marca de tiempo para las pistas de auditoría
#!/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 triaje de incidentes

El siguiente script completo reúne todos los conceptos en una herramienta práctica de triaje automatizado. Lee una lista de servicios críticos, consulta el journal de cada uno durante una ventana configurable de retrospectiva, agrega los hallazgos y termina con un código de error si se detectó algún error, por lo que resulta adecuado como tarea de cron o paso de comprobación de salud en 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}"

Comprobación de conocimientos: filtrado por intervalo de prioridades

Está escribiendo un script para alertar a los ingenieros de guardia únicamente cuando un servicio registre mensajes con una gravedad de error o superior (es decir, error, crítico, alerta o emergencia). ¿Qué combinación de opciones de journalctl captura exactamente ese intervalo?

Resumen de la lección: journalctl en scripts

En esta lección ha aprendido a consultar mediante programación el journal de systemd para realizar un triaje automatizado de incidentes:

  • Pase siempre --no-pager en los scripts para evitar bloqueos interactivos.
  • El filtrado por unidad (-u) limita las consultas a uno o más servicios; admite comodines y varias opciones -u.
  • El filtrado por prioridad (-p emerg..err) captura únicamente los niveles de gravedad que le interesan; recuerde que los números más bajos representan una mayor gravedad.
  • Las ventanas temporales (--since / --until) aíslan la salida de registros en una ventana de despliegue o un periodo de retrospectiva mediante marcas de tiempo legibles.
  • La limitación por arranque (-b -1) permite que los scripts post mortem lean los registros de una sesión de bloqueo anterior.
  • La salida JSON (-o json) y jq permiten crear canalizaciones estructuradas que alimentan sistemas de alertas o SIEM.
  • Las consultas basadas en cursores con --after-cursor evitan volver a procesar entradas antiguas en ejecuciones repetidas.
  • Las coincidencias nativas de campos (_COMM=, SYSLOG_IDENTIFIER=) son más rápidas que canalizar la salida a grep.

Combinar estas opciones en una función reutilizable de Bash le proporciona una herramienta de triaje preparada para producción que se integra limpiamente con cron, las canalizaciones de CI y los flujos de trabajo de alertas para ingenieros de guardia.

Preguntas frecuentes

¿La lección «Consulta de journald con journalctl en scripts» es gratis?

Sí — el texto completo de «Consulta de journald con journalctl en scripts» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Linux Command Line & Bash Scripting Mastery, actualiza a CoddyKit PRO. El curso de Linux Command Line & Bash Scripting Mastery incluye 4 lecciones en total.

¿Qué aprenderé en «Consulta de journald con journalctl en scripts»?

Filtre entradas del journal de systemd por unit, prioridad y hora para automatizar la clasificación inicial de incidentes. Practicas Linux Command Line & Bash Scripting Mastery con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar Linux Command Line & Bash Scripting Mastery?

No se requiere experiencia previa. Linux Command Line & Bash Scripting Mastery en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 3 de 4.

¿Cuánto tiempo toma la lección «Consulta de journald con journalctl en scripts»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de Linux Command Line & Bash Scripting Mastery?

Sí. Cada lección de Linux Command Line & Bash Scripting Mastery incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Análisis de registros web y de aplicaciones a gran escala
  2. Seguimiento de registros en tiempo real y alertas en streaming
  3. Consulta de journald con journalctl en scripts
  4. Cálculo de métricas e histogramas a partir de flujos de registros
← Volver a Linux Command Line & Bash Scripting Mastery