A las 03:12, la producción falló. Hiciste lo que hace cualquier persona sensata: acudiste a los registros. Y los registros hicieron lo que adoran hacer bajo estrés: se silenciaron, se rotaron o nunca salieron de la máquina.
Ubuntu 24.04 te ofrece dos realidades de logging que conviven: systemd-journald (el journal) y rsyslog (el syslog clásico). La elección no es “moderno vs legado”. Es “qué modos de fallo puedo tolerar”, “cómo demuestro que no perdí eventos” y “qué tan rápido puedo responder al responsable del incidente sin adivinar”.
La decisión: qué deberías ejecutar y por qué
Si ejecutas Ubuntu 24.04 en producción y te importa no perder eventos importantes, haz esto:
- Mantén journald. No es opcional en sistemas systemd y es tu mejor vista de primer respondedor.
- Haz persistente el journal en cualquier máquina que vayas a depurar después de un reinicio.
- Usa rsyslog para el reenvío duradero y controlable hacia una plataforma central de logs (SIEM, ELK/OpenSearch, Splunk, o lo que tu organización llame “la verdad”).
- No uses “reenviar todo dos veces” como estrategia. Los duplicados no son redundancia; son ruido que hace que pierdas la línea que necesitabas.
En otras palabras: journald para captura local, indexación y metadatos estructurados; rsyslog para compatibilidad con el ecosistema syslog, colas y reglas de reenvío deliberadas. Puedes reenviar desde journald a rsyslog, o hacer que los servicios registren directamente en syslog. La respuesta correcta depende de lo que necesites demostrar durante un incidente o auditoría.
Verdad seca: no eliges logging por sensaciones. Lo eliges por modo de fallo. Pregunta: “¿Qué pasa cuando el disco está lleno? ¿Cuando la red cae? ¿Cuando la máquina se reinicia? ¿Cuando el tiempo salta? ¿Cuando el proceso inunda el registrador?” y elige la pila que falle de la manera con la que puedas vivir.
Un modelo mental que no miente bajo presión
Qué es realmente journald
systemd-journald es un colector y almacén de eventos de registro con metadatos adjuntos: cgroup, nombre de unidad, PID, UID, capacidades, contexto SELinux/AppArmor (cuando está disponible), ID de arranque y marcas temporales monotónicas. Almacena entradas en archivos binarios de journal. “Binario” no es un fallo moral; es una elección de rendimiento e integridad. Permite indexado y consultas relativamente rápidas como “muéstrame todo de sshd.service en el último arranque”.
Por defecto en muchos sistemas, journald usa almacenamiento volátil (en memoria bajo /run/log/journal) a menos que se configure almacenamiento persistente. Ese valor por defecto es amigable para discos pequeños y máquinas efímeras, y brutal cuando necesitas depurar algo que ocurrió antes de un reinicio.
Qué es realmente rsyslog
rsyslog es un demonio syslog que ingiere mensajes (desde sockets locales, desde la red, desde journald vía un módulo de entrada) y luego los enruta según reglas. Es muy bueno manejando colas, límites de tasa, buffering asistido por disco y envío fiable cuando la red se comporta como una red (es decir: mal, a veces).
Las salidas de rsyslog suelen ser archivos de texto en /var/log o destinos syslog remotos. Los logs en texto siguen siendo la lingua franca de una cantidad deprimente de herramientas. No es nostalgia; es compatibilidad con cosas que aún analizan syslog como si fuera 2009.
El pipeline en Ubuntu 24.04 (típico)
- Los mensajes del kernel van al ring buffer del kernel, luego journald los recoge; rsyslog también puede leer mensajes del kernel según la configuración.
- Los servicios systemd registran en stdout/stderr; journald los captura automáticamente.
- Muchas aplicaciones tradicionales aún registran vía
/dev/log(socket syslog). Eso puede ser proporcionado por rsyslog o por el socket de compatibilidad syslog de systemd-journald. - rsyslog puede ingerir desde journald (vía
imjournal) o desde el socket syslog, luego escribir archivos y/o reenviar.
Si alguna vez te preguntaste por qué tu /var/log/syslog carece de una línea que viste en journalctl, la respuesta suele ser “esos son dos caminos de captura diferentes.” El logging es una cadena de suministro. No la notas hasta que un portacontenedores queda atascado.
Una cita para grapar en tu monitor (idea parafraseada): el tema operativo de Gene Kim es que la mejora viene de acortar los bucles de retroalimentación. El logging es uno de tus bucles más cortos; trátalo como código de producción.
Broma #1: Logging es como los dientes: lo ignoras hasta que duele, y entonces de repente estás dispuesto a pagar cualquier precio para que el dolor pare.
Hechos interesantes y contexto histórico
- syslog es anterior a Linux. El syslog original provino de BSD Unix en los años 80, diseñado para transporte de logs en red sencillo cuando el “modelo de seguridad” era mayormente “no dejar que Dave de contabilidad toque el servidor”.
- rsyslog es más nuevo de lo que la gente piensa. rsyslog se creó a principios de los 2000 como reemplazo drop-in de sysklogd con mejor rendimiento y características como TCP, RELP y colas.
- journald almacena logs en formato binario por diseño. Está optimizado para consultas indexadas y eventos ricos en metadatos; el argumento “los binarios son malos” se trata mayormente de expectativas de herramientas, no de la fiabilidad subyacente.
- systemd hizo de stdout/stderr un primer ciudadano para logging. Eso cambió la cultura de logging en aplicaciones: los servicios ya no tenían que gestionar archivos de log si no querían. La plataforma los captura.
- La rotación tradicional de logs se inventó para controlar el uso de disco de logs en texto. Con journald, la retención suele gestionarse por límites de tamaño/tiempo en lugar de rotación por nombre de archivo, lo que cambia cómo se responde a “¿guardamos la semana pasada?”.
- RELP existe porque TCP no fue suficiente. TCP aún puede perder datos cuando un remitente se bloquea o una conexión se reinicia en el momento inoportuno; RELP (Reliable Event Logging Protocol) añade acuses de recibo a nivel de aplicación.
- Journald etiqueta logs con un ID de arranque. Suena pequeño hasta que depuras un fallo intermitente y necesitas separar “este arranque” de “el arranque anterior”. Es un regalo.
- El ring buffer del kernel en Linux es finito. Si no lo drenas durante un pico, los mensajes viejos del kernel se sobrescriben. Eso no es culpa de journald, pero journald es tu ruta normal de drenaje.
Compromisos que realmente importan en 2025
Durabilidad: qué sobrevive al reinicio y qué no
journald puede ser volátil o persistente. journald volátil está bien para nodos tipo cattle donde centralizas todo instantáneamente, y es terrible para momentos de “¿por qué se reinició?” cuando tu forwarder no envió los últimos 30 segundos.
rsyslog escribiendo en disco es persistente por defecto (suponiendo que escriba en /var/log y que ese sistema de archivos sobreviva). Pero la persistencia en el mismo disco que tu carga no es una victoria si el disco se llena y tu app muere. La durabilidad es una propiedad del sistema, no del demonio.
Presión de retroceso y manejo de ráfagas
Bajo tormentas de logs, el sistema de logging se convierte en parte de tu perfil de rendimiento. journald tiene limitación de tasa y puede descartar mensajes. rsyslog puede poner en cola en memoria o volcar a disco. Si te importa “nunca perder logs de autenticación” o “capturar los últimos 60 segundos antes de un fallo”, necesitas ajustes explícitos y, normalmente, colas asistidas por disco.
Metadatos y ergonomía de consulta
journald gana localmente para corte rápido: por unidad, por PID, por cgroup, por arranque, por prioridad, por tiempo. Si estás respondiendo un incidente en una sola máquina, journalctl suele ser más rápido que hacer grep en archivos—especialmente cuando los servicios escupen datos estructurados o cuando los PID cambian.
rsyslog gana cuando necesitas integrar con todo lo que espera syslog, desde equipos de red hasta tuberías de cumplimiento antiguas. Es el “adaptador universal”.
Seguridad y resistencia a la manipulación
Ninguno de los dos demonios hace que los logs sean mágicamente a prueba de manipulaciones. El root local siempre puede hacer daño. Tu control real es: enviar logs fuera del host rápidamente, mantenerlos inmutables en el agregador y controlar el acceso. journald soporta funciones de sellado, pero no confundas “más difícil de editar casualmente” con “grado forense”.
Complejidad y coste operativo
Ejecutar solo journald es simple hasta que necesitas reenvío fiable con buffering, filtrado y opciones de protocolo. Ejecutar journald + rsyslog son un par de componentes más, pero te da control explícito del pipeline. En producción, explícito vence a implícito.
Broma #2: “No necesitamos logging centralizado” es una estrategia audaz; es como renunciar a los cinturones de seguridad porque planeas conducir con cuidado.
Tareas prácticas (comandos, significado de salidas, decisiones)
Estos son los chequeos que realizo en Ubuntu 24.04 cuando alguien dice “faltan logs”, “el disco se está llenando” o “el reenvío es inestable”. Cada tarea incluye: comando, qué significa la salida y qué decisión tomar.
Tarea 1: Confirma qué está en ejecución (journald, rsyslog)
cr0x@server:~$ systemctl status systemd-journald rsyslog --no-pager
● systemd-journald.service - Journal Service
Loaded: loaded (/usr/lib/systemd/system/systemd-journald.service; static)
Active: active (running) since Mon 2025-12-30 09:10:11 UTC; 2h 1min ago
...
● rsyslog.service - System Logging Service
Loaded: loaded (/usr/lib/systemd/system/rsyslog.service; enabled; preset: enabled)
Active: active (running) since Mon 2025-12-30 09:10:13 UTC; 2h 1min ago
...
Significado: Ambos servicios están activos; probablemente tienes logging con doble camino. Si rsyslog está inactivo, probablemente dependes únicamente de journald.
Decisión: Si necesitas reenvío remoto con buffering, habilita rsyslog (o un forwarder dedicado) y define la ruta intencionalmente.
Tarea 2: Ver el modo de almacenamiento de journald (volátil vs persistente)
cr0x@server:~$ journalctl --disk-usage
Archived and active journals take up 96.0M in the file system.
Significado: Hay archivos de journal en disco en algún lugar. Si este comando falla o muestra un uso pequeño pero esperabas historial, puede que sea solo volátil.
Decisión: Si te importan los logs tras reinicios, asegúrate de habilitar almacenamiento persistente y de tener ajustes de retención.
Tarea 3: Verificar si journald usa almacenamiento persistente
cr0x@server:~$ ls -ld /var/log/journal /run/log/journal
drwxr-sr-x 3 root systemd-journal 4096 Dec 30 09:10 /var/log/journal
drwxr-sr-x 2 root systemd-journal 120 Dec 30 09:10 /run/log/journal
Significado: /var/log/journal existe, así que la persistencia está activada (o al menos disponible). Si no existe, journald puede ser volátil.
Decisión: Si /var/log/journal falta, créalo y establece Storage=persistent (detalles en la sección de plan).
Tarea 4: Inspeccionar retención y límites de tasa de journald
cr0x@server:~$ systemd-analyze cat-config systemd/journald.conf
# /etc/systemd/journald.conf
[Journal]
Storage=persistent
SystemMaxUse=2G
SystemKeepFree=1G
RateLimitIntervalSec=30s
RateLimitBurst=10000
Significado: Estos son los ajustes efectivos después de los drop-ins. Un SystemMaxUse pequeño significa expulsión más rápida. La limitación de tasa agresiva puede descartar ráfagas.
Decisión: Ajusta según tu presupuesto de disco y necesidades de incidente. Si ves pérdidas durante picos, ajusta límites de tasa y envía fuera del host.
Tarea 5: Detectar mensajes descartados en journald
cr0x@server:~$ journalctl -u systemd-journald --since "1 hour ago" | tail -n 8
Dec 30 10:44:02 server systemd-journald[412]: Suppressed 12845 messages from /system.slice/myapp.service
Dec 30 10:44:02 server systemd-journald[412]: Forwarding to syslog missed 0 messages
Significado: “Suppressed” indica descartes por limitación de tasa. Eso no es teórico. Está ocurriendo.
Decisión: Si la unidad suprimida es importante (auth, kernel, tu servicio central), aumenta límites y reduce el spam en el origen. Considera colas de rsyslog para fiabilidad de reenvío.
Tarea 6: Comprobar si rsyslog ingiere desde journald
cr0x@server:~$ grep -R "imjournal" /etc/rsyslog.d /etc/rsyslog.conf
/etc/rsyslog.conf:module(load="imjournal" StateFile="imjournal.state")
Significado: rsyslog está leyendo desde el journal de systemd vía imjournal. Si falta, rsyslog puede estar leyendo desde /dev/log en su lugar.
Decisión: Elige una estrategia de ingestión para evitar duplicados: o imjournal (journal como fuente de la verdad) o socket (syslog como fuente). No hagas ambas por accidente.
Tarea 7: Detectar eventos duplicados (síntoma clásico de doble ingestión)
cr0x@server:~$ sudo awk 'NR<=20{print}' /var/log/syslog
Dec 30 11:01:10 server myapp[2211]: started worker=7
Dec 30 11:01:10 server myapp[2211]: started worker=7
Significado: El mismo mensaje dos veces con la misma marca temporal sugiere fuertemente doble ingestión (por ejemplo, la app escribe a syslog y journald lo reenvía a rsyslog también).
Decisión: Deshabilita un camino: o deja de reenviar desde journald a rsyslog, o evita que rsyslog lea /dev/log, según la arquitectura.
Tarea 8: Verificar las colas de rsyslog y si el reenvío está bloqueado
cr0x@server:~$ systemctl status rsyslog --no-pager | sed -n '1,14p'
● rsyslog.service - System Logging Service
Active: active (running) since Mon 2025-12-30 09:10:13 UTC; 2h 9min ago
Main PID: 621 (rsyslogd)
Tasks: 4
Memory: 8.5M
CPU: 1.901s
CGroup: /system.slice/rsyslog.service
└─621 /usr/sbin/rsyslogd -n -iNONE
Significado: El estado por sí solo no te dirá la profundidad de la cola, pero confirma salud del demonio y marca bucles de fallo obvios.
Decisión: Si el reenvío remoto está retrasado, comprueba la conectividad de red y las colas de acción de rsyslog (ver tareas de validación de configuración más abajo).
Tarea 9: Validar la configuración de rsyslog (sintaxis, módulos, includes)
cr0x@server:~$ rsyslogd -N1
rsyslogd: version 8.2312.0, config validation run (level 1), master config /etc/rsyslog.conf
rsyslogd: End of config validation run. Bye.
Significado: La validación pasó. Si muestra errores, rsyslog puede estar ejecutándose con config parcial o fallando al arrancar tras cambios.
Decisión: Nunca recargues rsyslog a ciegas en producción. Valida primero, luego recarga, y luego confirma el flujo de mensajes.
Tarea 10: Determinar si el reenvío es UDP (con pérdida) o TCP/RELP (mejor)
cr0x@server:~$ grep -R "@" /etc/rsyslog.d /etc/rsyslog.conf
/etc/rsyslog.d/60-forward.conf:*.* @@logrelay.internal:514
Significado: @ es UDP, @@ es TCP. TCP aún puede perder durante caídas; RELP es más fuerte.
Decisión: Si “no perder logs de auth” es requisito, no uses UDP. Usa TCP con colas en disco o RELP si tu relay lo soporta.
Tarea 11: Comprobar si journald está reenviando a syslog (y si lo necesitas)
cr0x@server:~$ grep -R "^ForwardToSyslog" /etc/systemd/journald.conf /etc/systemd/journald.conf.d 2>/dev/null
/etc/systemd/journald.conf:ForwardToSyslog=yes
Significado: journald está reenviando entradas al socket syslog. Si rsyslog también lee desde el journal, eso puede duplicar.
Decisión: Elige un único punto de entrega: o ForwardToSyslog (journald → socket syslog) o rsyslog imjournal (journald → rsyslog directamente).
Tarea 12: Identificar “¿por qué se reinició?” usando vistas separadas por arranque del journal
cr0x@server:~$ journalctl --list-boots | tail -n 3
-2 2f1c1b2dd0e84fbb9a1f66b2ff0f8d1e Sun 2025-12-29 22:10:17 UTC—Sun 2025-12-29 23:52:01 UTC
-1 7d8c0e3fa0f44a3b8c0de74b8b9f41a2 Mon 2025-12-30 00:10:06 UTC—Mon 2025-12-30 09:09:55 UTC
0 94f2b5d9f61e4f57b5f3c3c7a9c2a1d1 Mon 2025-12-30 09:10:06 UTC—Mon 2025-12-30 11:19:44 UTC
Significado: Se ven múltiples arranques, así que la persistencia funciona. Si solo ves “0”, probablemente eres volátil o el historial fue vaciado.
Decisión: Si los reinicios son misteriosos, asegura journald persistente y aumenta la retención para que “arranque anterior” exista cuando lo necesites.
Tarea 13: Extraer rápidamente la narrativa de apagado/caída
cr0x@server:~$ journalctl -b -1 -p warning..emerg --no-pager | tail -n 20
Dec 30 09:09:51 server kernel: Out of memory: Killed process 2211 (myapp) total-vm:...
Dec 30 09:09:52 server systemd[1]: myapp.service: Main process exited, code=killed, status=9/KILL
Dec 30 09:09:55 server systemd[1]: Reached target Reboot.
Significado: El último arranque muestra kill por OOM y muerte de servicio que conduce al reinicio. Este es el tipo de vista “una pantalla” en la que journald es excelente.
Decisión: Si los eventos del kernel/OOM son críticos, asegúrate de reenviarlos fuera del host y que no estén limitados por tasa bajo presión de memoria.
Tarea 14: Confirmar presión de disco en el sistema de archivos que aloja logs
cr0x@server:~$ df -h /var /run
Filesystem Size Used Avail Use% Mounted on
/dev/sda2 40G 34G 4.2G 90% /
tmpfs 3.1G 180M 2.9G 6% /run
Significado: /var está ajustado. Si los logs comparten el filesystem raíz, una ráfaga de logs puede convertirse en una indisponibilidad.
Decisión: Limita el uso de journald (SystemMaxUse), rota correctamente los logs en texto y envía fuera del host. Si es necesario, separa /var en su propio filesystem en entornos críticos.
Tarea 15: Cuantificar qué consumidores del journal son intensivos
cr0x@server:~$ journalctl --since "1 hour ago" -o json-pretty | head -n 20
{
"_SYSTEMD_UNIT" : "myapp.service",
"PRIORITY" : "6",
"MESSAGE" : "processed batch id=9f1c...",
"_PID" : "2211",
"__REALTIME_TIMESTAMP" : "1735557650000000"
}
Significado: La salida JSON muestra campos por los que puedes filtrar. Si tu app está emitiendo “processed batch …” a nivel info con mucho volumen, ese es tu problema de disco y de tu yo futuro.
Decisión: Reduce el volumen en origen. Los sistemas de logging no son sustituto de métricas.
Tarea 16: Comprobar quién tiene acceso al journal (permisos de depuración)
cr0x@server:~$ id
uid=1000(cr0x) gid=1000(cr0x) groups=1000(cr0x),4(adm)
Significado: Usuarios en adm a menudo pueden leer muchos logs; el acceso a journald se otorga comúnmente vía el grupo systemd-journal o mediante sudo.
Decisión: Da a los ingenieros on-call los grupos mínimos necesarios para leer logs sin dar root completo. Luego audita esa decisión trimestralmente, porque los organigramas se desplazan.
Guion de diagnóstico rápido
Estás de guardia. La alerta dice “servicio caído”. Alguien dice “faltan logs”. No te metas a hurgar sin método. Haz esto en orden.
Primero: averigua si los eventos existen localmente
- Revisa el journal para el servicio y el intervalo de tiempo. Filtra por unidad y prioridad. Si el journal lo tiene, tienes un punto de partida de verdad.
- Revisa el arranque anterior. Si el host se reinició, tus “logs faltantes” podrían ser simplemente “estás mirando el arranque equivocado”.
cr0x@server:~$ journalctl -u myapp.service --since "30 min ago" -p info..emerg --no-pager | tail -n 30
Dec 30 11:03:01 server myapp[2211]: healthcheck failed: upstream timeout
Dec 30 11:03:02 server systemd[1]: myapp.service: Main process exited, code=exited, status=1/FAILURE
Interpretación: Si el journal tiene el evento, el servicio está registrando y journald lo está recogiendo. Tu problema probablemente esté en el reenvío, filtros de duplicado o expectativas basadas en archivos syslog.
Segundo: determina si se está descartando datos
- Busca mensajes de supresión en journald.
- Comprueba presión de disco. Los discos llenos causan comportamientos extraños y escrituras perdidas.
- Revisa la salud de rsyslog y la validación de configuración.
Tercero: aisla el cuello de botella: captura, almacenamiento o envío
- Cuello de botella en captura: la aplicación no registra, stdout no está conectado, desajuste del socket syslog, permisos.
- Cuello de botella en almacenamiento: journald volátil, retención muy pequeña, disco lleno, vacuuming, rotación demasiado agresiva.
- Cuello de botella en envío: rsyslog reenviando por UDP, sin colas, pérdidas de red, problemas DNS para el host de logs, TLS mal configurado.
Cuarto: demuéstralo con un mensaje de prueba controlado
cr0x@server:~$ logger -p authpriv.notice "LOGTEST authpriv notice from $(hostname) at $(date -Is)"
cr0x@server:~$ journalctl --since "1 min ago" | grep LOGTEST | tail -n 1
Dec 30 11:18:22 server cr0x: LOGTEST authpriv notice from server at 2025-12-30T11:18:22+00:00
Interpretación: Si está en el journal pero no en /var/log/syslog (o no en tu agregador), has acotado la falla al camino de entrega/ envío.
Errores comunes: síntomas → causa raíz → solución
1) “Los logs desaparecen después del reinicio”
Síntomas: journalctl --list-boots muestra solo el arranque 0; la investigación tras un fallo no tiene historial.
Causa raíz: journald está usando almacenamiento volátil (/run) porque no se habilitó persistencia o /var/log/journal no existe.
Solución: Crea /var/log/journal, establece Storage=persistent, reinicia journald y confirma que aparecen múltiples arranques. También establece límites de retención para que la persistencia no termine agotando el disco.
2) “Tenemos duplicados por todas partes”
Síntomas: La misma línea aparece dos veces en /var/log/syslog o dos veces en el agregador, a menudo con marcas temporales idénticas.
Causa raíz: Doble ingestión: la app escribe al socket syslog mientras journald reenvía a syslog y rsyslog también lee del journal (o viceversa).
Solución: Escoge uno: rsyslog lee desde imjournal o journald reenvía al socket syslog. No combines sin lógica deliberada de deduplicación.
3) “Los logs de autenticación faltan en el sistema central, pero están localmente”
Síntomas: /var/log/auth.log está poblado localmente; el SIEM carece de entradas durante fallos de red.
Causa raíz: Reenvío por UDP, o TCP sin colas en disco, o una caída del relay sin buffering.
Solución: Usa TCP con colas asistidas por disco o RELP a un relay diseñado para ingestión. Verifica ajustes de cola y prueba bloqueando la red temporalmente.
4) “Durante un incidente, journalctl está lento o da tiempo de espera”
Síntomas: Las consultas con journalctl tardan mucho, CPU en picos, esperas de I/O.
Causa raíz: Journals enormes en discos lentos, volumen de logging agresivo o contención en el filesystem subyacente. A veces es simplemente que intenta renderizar demasiada salida.
Solución: Filtra agresivamente (unidad, prioridad, tiempo), limita uso en disco, vacía entradas antiguas y mantiene logs fuera de tu almacenamiento más lento cuando sea posible.
5) “/var está lleno y ahora todo está en llamas”
Síntomas: Servicios no arrancan, actualizaciones fallan, logs dejan de actualizarse, daemons se caen al azar.
Causa raíz: Logs en archivos sin límites, journald mal configurado en retención o una app descontrolada escribiendo a alta tasa.
Solución: Establece límites en journald (SystemMaxUse, SystemKeepFree), asegura que logrotate funcione y corrige la app ruidosa. Si el entorno es crítico, aísla /var en su propio filesystem.
6) “Puedo ver los logs con sudo, pero no como mi usuario de on-call”
Síntomas: journalctl muestra “No journal files were found” o permiso denegado sin sudo.
Causa raíz: El usuario on-call no está en el grupo correcto (systemd-journal o adm según política), o se aplicaron permisos reforzados.
Solución: Concede acceso de lectura controlado vía membresía de grupo, no credenciales compartidas de root, y documenta el proceso.
Tres mini-historias corporativas desde las trincheras del logging
Mini-historia 1: Un incidente causado por una suposición equivocada
Una empresa mediana migró una flota de Ubuntu 20.04 a 24.04. Tenían un runbook gastado: revisar /var/log/syslog, revisar /var/log/auth.log, enviar a syslog central. La migración “funcionó”, los servicios arrancaron y el equipo siguió con su trabajo.
Dos semanas después, un lote de nodos se reinició por un kernel panic provocado por un firmware defectuoso de la NIC. El on-call sacó /var/log/syslog y vio… no mucho. Parecía que la máquina se había reiniciado de forma educada. El responsable del incidente pidió “los últimos 60 segundos”. El on-call tenía 3 segundos y una sensación creciente de pánico.
La suposición equivocada fue sutil: asumieron que rsyslog seguía siendo el colector primario para todo lo importante. Pero varios servicios eran nativos de systemd y registraban en stdout; journald los capturó, y solo un subconjunto se reenviaba a rsyslog. Los eventos “faltantes” no estaban “perdidos”. Estaban en almacenamiento de journal volátil que desapareció tras el reinicio en algunos perfiles de nodo.
La solución fue aburrida y efectiva: habilitaron persistencia de journald en todos los nodos no efímeros, establecieron límites de tamaño sensatos y enroutaron journald a rsyslog en una única ruta explícita. El siguiente reinicio aún fue desagradable, pero al menos los logs contaron la historia en vez de engañar a todos.
Mini-historia 2: Una optimización que salió mal
Un gran equipo de plataforma interna decidió que pagaban demasiado por almacenamiento de logs. Notaron que el journal crecía rápido en nodos con mucho ruido. Así que bajaron la retención de journald agresivamente y endurecieron límites de tasa. Su objetivo era razonable: mantener discos sanos y reducir ruido.
Durante un mes pareció una victoria. El uso de disco bajó. Los dashboards se veían más limpios. Entonces una dependencia empezó a fallar: fallos intermitentes de handshake TLS entre servicios. Los fallos duraban segundos, solo unas pocas veces por hora. Las métricas mostraban picos de error, pero los logs que habrían explicado el porqué a menudo faltaban. Los picos eran exactamente el tipo de eventos que se suprimen por límites de tasa y retención corta cuando múltiples componentes se vuelven ruidosos simultáneamente.
Eventualmente hallaron un patrón correlacionando unos pocos logs sobrevivientes con capturas de paquetes: mismatch de MTU tras un cambio de red. La lección real no fue sobre MTU. Fue que “optimizaron” logging eliminando justo los datos necesarios para depurar eventos raros, los que no puedes reproducir a voluntad.
El enfoque corregido fue reducir volumen en origen (niveles de log, muestreo, diseño de eventos estructurados), mantener retención suficiente para triage local y confiar en un almacén central para forense a largo plazo. Cortar la retención es un bisturí; ellos lo usaron como una podadora.
Mini-historia 3: Una práctica aburrida pero correcta que salvó el día
Un equipo de pagos operaba nodos Ubuntu que manejaban autenticación. Nada glamoroso: servicios systemd, reenvío rsyslog y un relay central. El equipo tenía un hábito que parecía excesivo: cada trimestre ejecutaban una prueba controlada de “fallo de envío de logs” en horario laboral.
La prueba era simple. Bloqueaban el egress hacia el relay de logs por unos minutos en un host canario, generaban un puñado de mensajes de prueba con logger en diferentes facilities y prioridades, y luego reactivaban el egress. La expectativa: los mensajes se ponen en cola localmente y luego aparecen en el agregador en orden, sin pérdida.
Un trimestre, la prueba falló. Los mensajes nunca aparecieron aguas arriba. Los logs locales existían, pero el reenvío no se puso al día. Como fue una prueba y no una caída, tuvieron tiempo de investigar sin adrenalina. Resultó que un cambio de configuración había cambiado el reenvío a UDP “temporalmente” y nadie lo volvió a cambiar. “Temporal” es la palabra más permanente en IT corporativa.
Revirtieron a TCP con colas en disco y escribieron un pequeño chequeo en CI que señalaba reenvíos UDP en configuraciones de producción. Un mes después, un incidente real afectó el segmento de red de su datacenter. La cola absorbió la caída, el SIEM se puso al día después y la revisión del incidente incluyó una frase poco común: “No se observó pérdida de datos.” Lo aburrido ganó. De nuevo.
Listas de verificación / plan paso a paso
Plan A (recomendado): journald persistente + rsyslog con un solo punto de ingestión
-
Haz persistente journald.
cr0x@server:~$ sudo mkdir -p /var/log/journal cr0x@server:~$ sudo systemd-tmpfiles --create --prefix /var/log/journal cr0x@server:~$ sudo sed -i 's/^#Storage=.*/Storage=persistent/' /etc/systemd/journald.conf cr0x@server:~$ sudo systemctl restart systemd-journaldQué verificar:
journalctl --list-bootsdebería mostrar más que el arranque 0 después del siguiente reinicio, y/var/log/journaldebería poblarse. -
Establece límites de retención que no llenen discos.
cr0x@server:~$ sudo tee /etc/systemd/journald.conf.d/99-retention.conf >/dev/null <<'EOF' [Journal] SystemMaxUse=2G SystemKeepFree=1G MaxRetentionSec=14day EOF cr0x@server:~$ sudo systemctl restart systemd-journaldDecisión: Elige límites basados en el tamaño del disco y las necesidades de incidentes. En sistemas con raíz pequeña, sé conservador y envía fuera del host.
-
Elige la entrega a rsyslog: usa imjournal O ForwardToSyslog, no ambos.
Opción 1 (común): rsyslog lee el journal con imjournal.
cr0x@server:~$ sudo grep -R "module(load=\"imjournal" /etc/rsyslog.conf module(load="imjournal" StateFile="imjournal.state")Luego deshabilita el reenvío de journald a syslog para evitar duplicados si no lo estás usando:
cr0x@server:~$ sudo tee /etc/systemd/journald.conf.d/10-forwarding.conf >/dev/null <<'EOF' [Journal] ForwardToSyslog=no EOF cr0x@server:~$ sudo systemctl restart systemd-journald -
Usa reenvío fiable (TCP + colas; RELP si está disponible).
cr0x@server:~$ sudo tee /etc/rsyslog.d/60-forward.conf >/dev/null <<'EOF' # Forward everything to a relay over TCP with a disk-assisted queue. # Adjust rules so you don't forward noisy debug logs if you don't need them. action( type="omfwd" target="logrelay.internal" port="514" protocol="tcp" action.resumeRetryCount="-1" queue.type="LinkedList" queue.filename="fwdAll" queue.maxdiskspace="2g" queue.saveonshutdown="on" queue.dequeuebatchsize="500" ) EOF cr0x@server:~$ sudo rsyslogd -N1 cr0x@server:~$ sudo systemctl restart rsyslogDecisión: Si tienes requisitos de cumplimiento, combina esto con un relay interno y considera RELP/TLS. TCP solo es una buena línea base, no una garantía.
-
Demuestra el flujo extremo a extremo con mensajes controlados.
cr0x@server:~$ logger -p user.notice "LOGPIPE e2e test id=$(uuidgen)" cr0x@server:~$ journalctl --since "2 min ago" -o short-iso | grep LOGPIPE | tail -n 1 2025-12-30T11:20:41+00:00 server cr0x: LOGPIPE e2e test id=3e0c2aef-7e0f-4a43-a3c2-9c3e5c4f2f8bDecisión: Si aparece localmente pero no centralmente, arregla el envío. Si no aparece localmente, arregla la captura.
Plan B: solo journald (aceptable para flotas efímeras con centralización fuerte)
- Usa journald persistente solo si discos y políticas de retención lo permiten; de lo contrario confía en envío inmediato vía un colector compatible con journald.
- Establece límites de tasa estrictos con cuidado: podrías proteger el nodo a costa de perder el único evento que necesitabas.
- Asegúrate de tener siempre una copia fuera del host. “Solo local” es preludio de “no podemos demostrar qué pasó”.
Plan C: rsyslog como primario (solo si tienes restricciones legacy)
- Es posible, pero aún tendrás journald capturando stdout/stderr para servicios systemd.
- Si insistes en flujos basados en archivos, asegura que los servicios registren a syslog o a archivos intencionadamente. Si no, perseguirás eventos faltantes en dos mundos.
- Sé explícito sobre las fuentes de logging del kernel para evitar huecos.
Preguntas frecuentes
1) En Ubuntu 24.04, ¿necesito rsyslog en absoluto?
Si necesitas diseños clásicos de archivos syslog, reglas de ruteo finas, colas asistidas por disco o compatibilidad amplia con el ecosistema syslog, sí. Si tienes un colector nativo de journald que envía fuera del host de forma fiable, puedes prescindir de rsyslog.
2) ¿Perderá journald logs?
Puedes perderlos. Si está configurado como volátil, los logs no sobrevivirán al reinicio. Si entran límites de tasa, puede suprimir mensajes durante ráfagas. Si el disco está lleno o los límites de retención son bajos, se vacían entradas antiguas. Nada de eso es maldad; es física.
3) ¿Los logs binarios son un problema para cumplimiento?
Usualmente el requisito de cumplimiento es “retención, integridad, control de acceso, auditabilidad”, no “debe ser texto plano”. La jugada real para cumplimiento es enviar fuera del host a almacenamiento inmutable y controlar el acceso. Binario vs texto es preferencia de herramientas, no una garantía.
4) ¿Por qué veo logs en journalctl pero no en /var/log/syslog?
Porque journald captura stdout/stderr de servicios systemd por defecto. A menos que reenvíes esas entradas a syslog, no aparecerán en archivos syslog. Además, filtros o mapeos de facility pueden enrutar mensajes de forma distinta.
5) ¿Debería reenviar desde journald a rsyslog o hacer que rsyslog lea el journal?
Escoge uno, según claridad y evitar duplicados. Yo prefiero que rsyslog lea el journal vía imjournal para tener un único punto de ingestión con colas y acciones de reenvío explícitas.
6) ¿Es aceptable el reenvío syslog por UDP alguna vez?
Para telemetría de bajo riesgo y streams de debug ruidosos donde la pérdida es aceptable, sí. Para autenticación, seguridad o logs críticos de incidentes: no. Usa TCP con buffering, o RELP si puedes.
7) ¿Cuánta retención del journal debería mantener?
Mantén lo suficiente para cubrir tu ventana de respuesta humana: al menos “arranque previo + unos días” en hosts importantes. Luego confía en la retención central para semanas/meses. Restringe el uso local para que no pueda comerse la máquina.
8) ¿Puedo hacer que journald escriba logs tradicionales en texto directamente?
No como su formato primario. journald puede reenviar a syslog, y demonios syslog pueden escribir archivos de texto. Ese es el puente soportado: journald captura, rsyslog escribe/reenvía.
9) ¿Qué pasa con los logs de contenedores?
Si los contenedores registran en stdout/stderr y el runtime se integra con systemd, journald puede capturar con metadatos ricos. Si usas otra ruta de runtime, asegúrate de que tu colector tome explícitamente logs de contenedores. No supongas.
10) ¿Cómo evito que los logs tumben el nodo?
Limita el uso de disco de journald, asegura que logrotate funcione para logs en texto y reduce el volumen de logs en origen. También evita poner logging pesado en el mismo filesystem restringido que tu base de datos.
Conclusión: pasos siguientes que no te traicionarán
Ubuntu 24.04 no impone una guerra religiosa entre journald y rsyslog. Te ofrece dos herramientas con distintos modos de fallo. En producción, el patrón correcto suele ser: journald persistente para la verdad local, más rsyslog para reenvío deliberado, con buffer y compatibilidad.
Próximos pasos:
- Haz journald persistente en cualquier host que puedas depurar tras un reinicio, y límitalo para que no pueda llenar discos.
- Decide tu único punto de ingestión hacia rsyslog para evitar duplicados.
- Cambia el reenvío a TCP (o RELP) con colas asistidas por disco para todo aquello que no puedas permitirte perder.
- Ejecuta trimestralmente una prueba de “fallo de envío de logs” en un canario. Si suena excesivo, espera hasta tu primera auditoría o incidente de seguridad.
El logging no es solo observabilidad. Es evidencia. Contrúyelo como si lo fueras a necesitar en un juicio—porque algún día, internamente, lo necesitarás.