journalctl: analizar los logs de systemd y conservarlos

Publicado el 21 min de lectura

Ventanas de tiempo, filtros por unit, prioridades y patrones de búsqueda: cómo recortar en tres o cuatro comandos justo el fragmento que corresponde a la incidencia. Además, un journal que sobrevive a los reinicios y los mensajes de error citados palabra por palabra.

Cuando algo va mal en un servidor, lo habitual es que la máquina ya haya dejado escrito lo que ha pasado. El problema no es la falta de información, sino la cantidad en la que está. Quien llama a journalctl sin argumentos aterriza al principio del journal y se pone a pasar mensajes de hace semanas. Esta guía te enseña a recortar, en tres o cuatro comandos, justo el fragmento que corresponde a la incidencia.

El artículo crear un servicio systemd presenta las formas básicas -u, -b y -f. Aquí va todo lo que viene después: ventanas de tiempo, filtros, prioridades, formatos de salida, cómo conservar el journal de forma permanente, límites de tamaño, mensajes del kernel y patrones de búsqueda listos para usar.

Todos los datos se refieren a Debian 13 (trixie), Debian 12 (bookworm), Ubuntu 24.04 LTS y Ubuntu 22.04 LTS. Los comandos están escritos para ejecutarse como root. Si trabajas como usuario normal, antepón sudo a cada comando.

Antes de cambiar nada: el camino de vuelta

Leer el journal no tiene ningún riesgo: ningún comando de búsqueda de este artículo modifica nada en el sistema. Hay exactamente tres cosas que sí son arriesgadas, y todas llegan más adelante.

Un sistema de archivos lleno. Sin un límite propio, el journal ocupa hasta el diez por ciento del sistema de archivos, con un tope de cuatro gigabytes. En un disco pequeño, un /var lleno es el camino corto hacia un servidor que ya no acepta ningún inicio de sesión.

Una errata en la configuración. systemd ignora las claves desconocidas en lugar de detener el servicio. Tu límite queda escrito en el archivo, pero no surte efecto, y nadie te lo dice si no preguntas.

Una limpieza precipitada. journalctl --vacuum-time=1d borra de forma irreversible, también las pruebas que justo estabas buscando.

La vía de rescate para el peor de los casos: en los servidores root KVM y en los servidores dedicados de KernelHost no hay IPMI ni iDRAC. El acceso que sigue funcionando incluso sin red es la consola VNC del área de cliente. Cuelga de la capa de virtualización, o del propio puerto del servidor, no del stack de red del sistema invitado. Entra ahí una vez antes de empezar y asegúrate de conocer la contraseña de root.

Inventario en 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

El cuarto comando es el más importante: responde a la pregunta de si tu journal sobrevive a un reinicio y devuelve No such file or directory para el directorio que no exista. Todos los cambios de este artículo acaban después en un archivo propio bajo /etc/systemd/journald.conf.d/. El /etc/systemd/journald.conf que trae la distribución queda intacto, y deshacerlo todo son dos comandos: borrar el archivo y reiniciar el servicio.

Acotar la ventana de tiempo en lugar de hacer scroll

Casi toda incidencia tiene una marca de tiempo. Por ahí empieza el análisis, no por el nombre del servicio.

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

--since y --until tienen las formas cortas -S y -U. Como indicación temporal, journalctl entiende valores absolutos con el formato 2026-09-02 03:10:00, fechas sin hora (en ese caso vale la medianoche), las palabras clave yesterday, today, tomorrow y now, además de indicaciones relativas como -1h, -30min o 2 days ago.

Aquí se esconde una trampa que cuesta mucho tiempo: journalctl trabaja en la hora local del servidor, mientras que las aplicaciones a menudo escriben sus logs en UTC. Si metes sin comprobar en --since una marca de tiempo sacada de un log de aplicación, en verano acabas buscando dos horas al lado del evento. Comprueba la zona horaria o pide directamente que todo se muestre en UTC:

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

Comprobación: si vuelve -- No entries --, o la ventana es demasiado estrecha o la zona horaria es la equivocada. Amplía la ventana a una hora como prueba antes de empezar a dudar de los filtros.

Los arranques como ventana de tiempo

A menudo el fragmento adecuado no es un intervalo de horas, sino un arranque del sistema. -b sin valor se refiere al que está en curso y -b -1 al anterior.

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

La lista muestra una línea por arranque con un índice, y el que está en curso lleva el 0. Si solo aparece esa única línea, lo más probable es que el journal no se guarde de forma permanente. Entonces -b -1 responde en Debian 13 con No journal boot entry found for the specified boot (-1) y en Ubuntu 24.04 con No journal boot entry found from the specified boot offset (-1). No es una avería, sino el aviso de que ahí no hay nada que rescatar.

Filtrar por servicio, proceso y prioridad

La unit, y por qué el nombre tiene que ser exacto

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

-u compara por igualdad, no por parecido. De ahí sale un fallo especialmente molesto, porque no genera ningún mensaje de error: en un sistema Debian con MariaDB, journalctl -u mysql devuelve -- No entries -- aunque el journal esté lleno de mensajes de la base de datos. Allí mysql.service es solo un alias de mariadb.service. systemctl resuelve esos alias, pero el journal guarda bajo el nombre real. Recibes por tanto una respuesta equivocada que no tiene pinta de error.

El nombre real lo sacas del propio journal. -F lista todos los valores que un campo ha tenido alguna vez ahí:

journalctl -F _SYSTEMD_UNIT | sort | grep -i sql

Además, -u acepta patrones, lo que le quita hierro al asunto:

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

La misma comprobación merece la pena en Ubuntu 24.04 con SSH, porque allí el servicio arranca mediante activación por socket y los inicios de sesión no tienen por qué figurar bajo el nombre esperado:

journalctl -F _SYSTEMD_UNIT | grep -i ssh

El identificador en lugar de la unit

Junto a la unit existe el identificador del emisor, es decir, lo que el syslog clásico maneja como nombre del programa. El filtro para eso es -t:

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

¿Por qué dos? Desde la versión 9.8, OpenSSH traslada las sesiones a un proceso propio llamado sshd-session. Por eso, en Debian 13 (OpenSSH 10.0) bajo -t sshd solo queda constancia de que el servicio está escuchando, mientras que cada inicio de sesión se encuentra bajo -t sshd-session. Debian 12 (9.2), Ubuntu 24.04 (9.6) y Ubuntu 22.04 (8.9) no conocen esa división. Quien en Debian 13 filtra solo por -t sshd da por tranquilo un servidor en el que se está registrando cada intento. El camino a través de la unit es más robusto, porque los procesos hijos pertenecen a la misma:

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

Cualquier campo, y cómo se combinan

Cada entrada lleva campos que puedes escribir directamente como filtro, por ejemplo _COMM (nombre del programa), _PID, _UID, _SYSTEMD_UNIT o _TRANSPORT. Las reglas de combinación se suelen dar por supuestas de forma equivocada:

  • Dos filtros sobre campos distintos se combinan con un Y lógico.
  • Dos filtros sobre el mismo campo se combinan con un O lógico.
  • Un signo más suelto entre dos grupos combina los grupos con un O lógico.
journalctl _SYSTEMD_UNIT=ssh.service _UID=0 --since "-1h" --no-pager
journalctl _SYSTEMD_UNIT=ssh.service + _SYSTEMD_UNIT=nginx.service --since "-1h" --no-pager

Los nombres de campo van en mayúsculas y la comparación se hace sobre el valor completo. Por eso journalctl unit=nginx no es un filtro por subcadena, sino un error de sintaxis que journalctl responde con Failed to add match.

Prioridades

Cada entrada lleva un nivel de urgencia del 0 al 7. -p filtra por él e incluye siempre todos los niveles más urgentes: -p err muestra también crit, alert y emerg.

NivelNombreSignificado
0emergSistema inservible
1alertHace falta intervenir de inmediato
2critError crítico en un componente
3errError, una tarea se ha quedado sin hacer
4warningAviso, el servicio sigue funcionando
5noticeDigno de mención, pero normal
6infoMensaje de funcionamiento normal
7debugSolo para buscar errores
journalctl -b -p err --no-pager
journalctl -u nginx.service -p 2..4 --since "-24h" --no-pager

Y ahora la trampa con la que el filtrado por prioridad falla una y otra vez: lo que un servicio escribe en la salida estándar acaba por defecto en el journal como info, aunque haya salido por la salida de error estándar. Un programa que imprime una excepción con su stack trace aparece así como un inofensivo mensaje de funcionamiento, y -p err lo esconde. Solo reciben un nivel adecuado los programas que escriben directamente contra la interfaz del journal o que anteponen a sus líneas un prefijo de syslog como <3>. Por eso, en tus propios servicios filtra por unit y por texto; en los servicios del sistema y en el kernel, -p sí que resulta útil.

Búsqueda de texto

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

--grep (forma corta -g) busca únicamente en el texto del mensaje, no en el resto de campos. Las mayúsculas y minúsculas se ignoran de forma automática mientras el patrón esté escrito íntegramente en minúsculas; en cuanto aparece una mayúscula, la comparación pasa a ser exacta. Ambos comportamientos se pueden forzar con --case-sensitive=yes o --case-sensitive=no. Se admiten expresiones regulares, así que la barra vertical funciona como un O lógico.

Seguir el log en directo

-f se engancha al final del journal y muestra las líneas nuevas en cuanto llegan. Esto solo tiene sentido con un filtro, porque si no pasa por delante medio sistema. -n determina cuántas líneas anteriores aparecen al principio: sin indicar nada son diez. Se termina con Ctrl+C.

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

El procedimiento habitual para un fallo reproducible: en la primera sesión te quedas leyendo y en una segunda provocas el fallo. Con líneas muy anchas ayuda -o cat, porque entonces solo aparece el texto del mensaje, sin marca de tiempo ni emisor.

Comprobación: si al provocarlo no llega absolutamente nada, el servicio no escribe en el journal, sino en un archivo propio. En servidores web y bases de datos ese es el caso normal. Entonces el camino pasa por la configuración de la aplicación, no por más opciones de journalctl.

Formatos de salida

El formato estándar está pensado para personas delante de un terminal. Para cotejar con otros logs, para pipes y para análisis hay otros más apropiados. Se cambia con -o:

FormatoPara qué
shortvalor por defecto, hora local con precisión de segundo
short-isomarca de tiempo según ISO 8601 con el desfase de zona, ideal para cotejar
short-precisecomo short, pero con fracciones de segundo
short-monotonicsegundos desde el arranque del sistema, útil para problemas de arranque
short-unixtiempo Unix, cómodo para seguir calculando
catsolo el texto del mensaje, pensado para pipes
verbosetodos los campos de una entrada, así se aprenden los nombres de campo
json-prettylegible por máquinas y aun así legible
journalctl -u ssh.service -n 1 -o verbose --no-pager

Ese único comando vale más que cualquier lista de campos de un manual: ves qué campos llevan realmente tus entradas y después puedes usar cualquiera de ellos como filtro. Cuatro opciones lo completan:

  • --no-pager desactiva el pager. En scripts y antes de cualquier pipe es obligatoria, porque si no la llamada se queda esperando una tecla que nadie va a pulsar.
  • -r invierte el orden y deja arriba las líneas más recientes.
  • -e salta en el pager directamente al final.
  • -x añade, en los mensajes propios de systemd, un texto explicativo del catálogo.

Con --output-fields= se puede reducir la salida a los campos que interesan. Solo surte efecto en verbose, json y formatos emparentados:

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

Conservar el journal entre reinicios

Que el journal sobreviva a un reinicio lo decide el valor por defecto Storage=auto con una regla sencilla: si existe /var/log/journal, se escribe ahí y todo se conserva. Si no existe, todo acaba en la RAM bajo /run/log/journal y desaparece con el siguiente reinicio. No te fíes de la distribución, porque entre variantes de instalación e imágenes de cloud se dan los dos casos. Un journal en RAM es la explicación más frecuente de que, tras una caída, ya nadie pueda decir qué pasó antes.

Si haces el cambio, fija el límite en el mismo paso. Por experiencia, después ya no se hace:

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

Storage=persistent crea el directorio por su cuenta, para eso no hace falta ningún mkdir. journalctl --flush traslada a /var/log/journal lo que todavía queda en /run.

Comprobaciones, en este orden:

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

El primer comando muestra la configuración efectiva a partir del archivo principal y de todos los archivos complementarios, es decir, lo que el servicio ha leído de verdad. El tercero es la prueba de erratas: si ahí aparece una línea con Unknown key, tu ajuste no surte efecto. Según la versión de systemd dice Unknown key name 'SystemMaxUsage' in section 'Journal', ignoring o Unknown key 'SystemMaxUsage' in section [Journal], ignoring.

La prueba definitiva es un reinicio de verdad. Después, journalctl --list-boots tiene que mostrar al menos dos líneas y journalctl -b -1 -n 20 tiene que devolver entradas. Si prefieres crear el directorio a mano, este es el camino. La llamada a systemd-tmpfiles se encarga del propietario, de los permisos y de las listas de control de acceso que permiten leer a los grupos correspondientes:

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

Leer sin ser root

Un usuario normal solo ve sus propios mensajes y recibe además el aviso Hint: You are currently not seeing messages from other users and the system. junto con la referencia a los grupos que pueden leerlo todo. En Debian y en Ubuntu ese grupo suele ser adm:

usermod -aG adm nombredeusuario

Comprobación: la pertenencia al grupo no vale hasta un inicio de sesión nuevo. Así que cierra la sesión, vuelve a iniciarla y ejecuta id -nG y journalctl -n 5. Si el aviso ya no aparece y sí salen mensajes del sistema, ha funcionado.

Limitar el tamaño antes de que lo haga el disco

ClaveEfecto
SystemMaxUselímite superior para el journal en disco
SystemKeepFreeespacio en disco que el journal deja libre
RuntimeMaxUselo mismo para el journal en RAM bajo /run
MaxRetentionSecedad máxima de las entradas, con independencia del tamaño

El /etc/systemd/journald.conf que trae la distribución lista todas las claves como líneas comentadas con sus valores por defecto y es, por tanto, la fuente más fiable de lo que rige ahora mismo en tu sistema. Después de cada cambio hace falta systemctl restart systemd-journald, y a continuación journalctl --disk-usage muestra el resultado.

Para la medida inmediata en un disco lleno hay un orden con el que mucha gente tropieza: las opciones de limpieza solo tocan los archivos de journal ya cerrados, nunca el que está activo en ese momento. Sin rotar antes no pasa aparentemente nada, y la salida viene a decir Vacuuming done, freed 0B of archived journals.

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

Más sobre esto, junto con el resto de devoradores de espacio, en el artículo disco lleno en Linux.

Un segundo motivo para las líneas que faltan es el limitador de tasa integrado, a través de RateLimitIntervalSec y RateLimitBurst: si un servicio escribe muchísimos mensajes en poco tiempo, journald descarta el excedente y lo deja anotado con una línea que contiene la palabra Suppressed. Si un log tiene huecos aunque está demostrado que el servicio estaba en marcha, busca eso primero:

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

Mensajes del kernel: journalctl -k y dmesg

-k muestra únicamente los mensajes del kernel e incluye de paso -b, de modo que limita la salida automáticamente al arranque en curso. Quien busca la causa después de un reinicio tiene que pedir el arranque anterior de forma explícita:

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

La diferencia con dmesg está en dónde se guardan los datos. dmesg lee el búfer circular del kernel: limitado, se desborda y queda vacío tras un reinicio. El journal conserva esos mismos mensajes siempre que sea persistente. Para un incidente de ayer, journalctl -k es por tanto la única fuente fiable. A esto se suman dos apuntes prácticos: dmesg -T convierte los segundos transcurridos desde el arranque en horas y, tras tiempos de actividad largos, se desvía un poco, mientras que el journal siempre lleva la hora real. Y kernel.dmesg_restrict vale 1 en las cuatro distribuciones, así que una llamada sin root falla con Operation not permitted.

Por qué muchos servidores ya no tienen /var/log/syslog

El journal no es un añadido a los clásicos archivos de texto, sino su sustituto. /var/log/syslog y /var/log/auth.log no los crea systemd, sino un servicio de syslog adicional, normalmente rsyslog. Ese es un paquete aparte y, en las instalaciones mínimas de Debian 12 y Debian 13, ya no viene incluido. En las imágenes de servidor de Ubuntu 22.04 y 24.04 sí está presente.

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

Si no hay ningún servicio de syslog instalado, el segundo comando responde con Unit rsyslog.service could not be found. Eso explica tres observaciones de una sola vez: las guías con tail -f /var/log/syslog fallan con tail: cannot open '/var/log/syslog' for reading: No such file or directory, la búsqueda de intentos de inicio de sesión en /var/log/auth.log se queda en nada, y fail2ban tiene que sacar sus eventos del journal. Cómo se configura eso está en el artículo configurar Fail2ban.

Instalar rsyslog a posteriori solo porque uno está acostumbrado a esos archivos rara vez compensa: entonces guardas todo por duplicado y necesitas además una regla de logrotate que funcione. Tiene sentido cuando los logs deben ir a un sistema central.

Patrones de búsqueda listos para la emergencia

Un servicio ha muerto o se reinicia sin parar

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

La tercera línea encuentra los mensajes con los que systemd acusa las caídas y su freno de arranque integrado. Si un volcado de memoria resulta interesante, este archivo aclara primero quién se encarga de él:

cat /proc/sys/kernel/core_pattern

Si ahí figura una llamada a systemd-coredump, coredumpctl list enumera los volcados disponibles. Si figura otra cosa o solo core, se encarga otro handler y coredumpctl se queda vacío.

Falta de memoria

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

El segundo comando renuncia a propósito a -k y busca así a lo largo de varios arranques. El tercero vale para Ubuntu 22.04 y 24.04, donde systemd-oomd viene activo de fábrica y termina control groups enteros antes de que intervenga el kernel; en Debian ese servicio no forma parte del equipamiento estándar. Cómo distinguir unos mensajes de otros está en el artículo configurar swap y evitar el Out of Memory.

Inicios de sesión fallidos

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

Más interesante que las líneas sueltas es la distribución. La siguiente línea cuenta las direcciones de origen y las ordena de mayor a menor:

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

El truco está en contar desde el final: el mensaje siempre termina en from DIRECCION port NUMERO ssh2, así que el cuarto campo empezando por atrás es la dirección, tanto si delante había un nombre de usuario válido como si era inventado, y da igual que sea IPv4 o IPv6. Aquí -o cat es obligatorio, porque si no la marca de tiempo y el emisor desplazan la cuenta de campos. La contraprueba para los inicios de sesión correctos:

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

¿Qué pasó a las 03:14 y qué vino 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

El segundo comando muestra las últimas cien líneas antes del final anterior. Un apagado ordenado se reconoce porque systemd va terminando servicios uno tras otro. Si la salida se corta en pleno funcionamiento normal, fue una caída, un reset en frío o un corte de corriente. Con el tercer comando ten presente que los números de proceso se reutilizan: sin una ventana de tiempo quizá estés mezclando dos programas distintos en la misma salida.

Errores frecuentes y soluciones

No journal files were found.: no hay archivos de journal legibles. O bien systemd-journald no está en marcha, o bien como usuario normal no tienes acceso. Comprueba primero systemctl is-active systemd-journald y repite después como root.

-- No entries --: el filtro no ha encontrado nada. No es un mensaje de error, sino una respuesta correcta a una pregunta posiblemente equivocada. Las tres causas más frecuentes: un nombre de unit que solo es un alias, una ventana de tiempo demasiado estrecha y un -k pese a que el mensaje buscado no venía del kernel.

Hint: You are currently not seeing messages from other users and the system.: estás leyendo como usuario normal. Entra en el grupo adm y vuelve a iniciar sesión, o trabaja directamente con sudo.

No journal boot entry found for the specified boot (-1) o bien No journal boot entry found from the specified boot offset (-1): en el journal no hay ningún arranque anterior. Es lo normal mientras el journal solo esté en la RAM.

Failed to add match: la expresión no es un filtro de campo válido. Los nombres de campo van en mayúsculas y la comparación se hace sobre el valor completo. Para las coincidencias parciales en el texto del mensaje está --grep.

Unknown key name 'SystemMaxUsage' in section 'Journal', ignoring: una errata en el archivo complementario. systemd se salta la línea y sigue trabajando con el valor por defecto. Se localiza con journalctl -u systemd-journald -b.

Vacuuming done, freed 0B of archived journals: no había nada archivado que borrar, porque el espacio lo ocupa el archivo activo. Primero journalctl --rotate y después vuelve a limpiar.

Operation not permitted con dmesg: kernel.dmesg_restrict vale 1. Repite como root o recurre a journalctl -k.

File /var/log/journal/.../system.journal corrupted or uncleanly shut down, renaming and replacing.: el servidor se apagó de golpe mientras había un archivo de journal abierto. journald le añade una virgulilla (~) al nombre antiguo y empieza un archivo nuevo. El estado de todos los archivos lo comprueba journalctl --verify, que imprime una línea con PASS por archivo; las objeciones afectan casi siempre justo a esos archivos antiguos terminados en ~.

Diferencias entre Debian 13, Debian 12, Ubuntu 24.04 y 22.04

  • Debian 13 (trixie): systemd 257. OpenSSH 10.0, los inicios de sesión figuran bajo el identificador sshd-session. rsyslog no está presente en las instalaciones mínimas, así que entonces falta /var/log/syslog. systemd-oomd no forma parte del equipamiento estándar.
  • Debian 12 (bookworm): systemd 252. OpenSSH 9.2, todo bajo sshd. rsyslog está presente según la variante de instalación, de modo que /var/log/syslog no está garantizado. systemd-oomd no forma parte del equipamiento estándar.
  • Ubuntu 24.04 LTS: systemd 255. OpenSSH 9.6, todo bajo sshd. rsyslog presente. systemd-oomd activo de fábrica. SSH funciona con activación por socket, así que conviene consultar en el journal el nombre real de la unit.
  • Ubuntu 22.04 LTS: systemd 249. OpenSSH 8.9, todo bajo sshd. rsyslog presente. systemd-oomd activo de fábrica. Es la más antigua de las cuatro versiones de systemd y allí faltan algunos formatos de salida más recientes.

Lo esencial es igual en los cuatro sistemas: los mismos filtros, las mismas prioridades, el mismo archivo de configuración y la misma regla, la de que /var/log/journal decide la durabilidad.


El orden que funciona en el día a día: primero la ventana de tiempo, después la unit, después la prioridad y, al final, un patrón de búsqueda. Quien procede así no necesita ni tres comandos para la mayoría de las incidencias. Y quien se ocupa una sola vez de que el journal sobreviva a los reinicios y tenga aun así un límite superior puede seguir respondiendo a la pregunta del porqué incluso cuando el servidor lleve rato funcionando de nuevo.

Preguntas frecuentes

¿Cómo acoto el journal al periodo de la incidencia?
Primero la ventana de tiempo y solo después el nombre del servicio y la prioridad. journalctl --since "-30min" te da la última media hora, journalctl --since "2026-09-02 03:10" --until "2026-09-02 03:20" un intervalo fijo, y las formas cortas se llaman -S y -U. Presta atención a la zona horaria: journalctl trabaja en la hora local del servidor, mientras que las aplicaciones a menudo escriben sus logs en UTC. Si metes sin comprobar una marca de tiempo sacada de un log de aplicación, en verano acabas buscando dos horas al lado del evento. Si vuelve -- No entries --, amplía la ventana a una hora como prueba antes de empezar a dudar de los filtros.
¿Por qué journalctl -u mysql no devuelve ninguna línea aunque la base de datos escriba logs?
Porque -u compara por igualdad y no por parecido. En un sistema Debian con MariaDB, mysql.service es solo un alias de mariadb.service, pero el journal guarda sus entradas bajo el nombre real. Por eso recibes -- No entries -- y ningún mensaje de error, es decir, una respuesta equivocada que no tiene pinta de error. El nombre real lo sacas con journalctl -F _SYSTEMD_UNIT | sort | grep -i sql. También puedes quitarle hierro al asunto con patrones, porque -u los acepta: journalctl -u "mysql*" -u "mariadb*" -n 60 --no-pager.
¿Por qué los inicios de sesión SSH en Debian 13 no aparecen bajo journalctl -t sshd?
Desde la versión 9.8, OpenSSH traslada las sesiones a un proceso propio llamado sshd-session. Por eso, en Debian 13 (OpenSSH 10.0) bajo -t sshd solo queda constancia de que el servicio está escuchando, mientras que cada inicio de sesión se encuentra bajo -t sshd-session. Debian 12, Ubuntu 24.04 y Ubuntu 22.04 no conocen esa división. Quien en Debian 13 filtra solo por -t sshd da por tranquilo un servidor en el que se está registrando cada intento. El camino a través de la unit es más robusto, porque los procesos hijos pertenecen a la misma: journalctl -u ssh --since "-24h".
¿Por qué -p err no muestra los errores de mi propio servicio?
Lo que un servicio escribe en la salida estándar acaba por defecto en el journal como info, aunque haya salido por la salida de error estándar. Un programa que imprime una excepción con su stack trace aparece así como un inofensivo mensaje de funcionamiento, y -p err lo esconde. Solo reciben un nivel adecuado los programas que escriben directamente contra la interfaz del journal o que anteponen a sus líneas un prefijo de syslog. Por eso, en tus propios servicios filtra por unit y por texto; en los servicios del sistema y en el kernel, -p sí que resulta útil.
¿Cómo consigo que el journal sobreviva a un reinicio?
Con el valor por defecto Storage=auto lo decide un único directorio: si existe /var/log/journal, todo se conserva. Si no existe, el journal queda en la RAM bajo /run/log/journal y desaparece con el siguiente reinicio. Crea un archivo propio bajo /etc/systemd/journald.conf.d/, pon ahí Storage=persistent junto con un límite superior como SystemMaxUse=500M y MaxRetentionSec=1month, reinicia el servicio con systemctl restart systemd-journald y recupera con journalctl --flush lo que todavía quede en /run. La prueba es un reinicio de verdad: después, journalctl --list-boots tiene que mostrar al menos dos líneas.
¿Qué significa "No journal boot entry found for the specified boot (-1)"?
En el journal no hay ningún arranque anterior. En Ubuntu 24.04 la misma afirmación se lee como "No journal boot entry found from the specified boot offset (-1)". No es una avería, sino el aviso de que ahí no hay nada que rescatar, y es lo normal mientras el journal solo esté en la RAM. Si journalctl --list-boots muestra también una única línea, lo más probable es que no se esté guardando de forma permanente. Quien quiera analizar en el futuro el arranque anterior tiene que pasar antes a Storage=persistent.
¿Por qué journalctl --vacuum-time no libera espacio?
Las opciones de limpieza solo tocan los archivos de journal ya cerrados, nunca el que está activo en ese momento. Sin rotar antes no pasa aparentemente nada, y la salida viene a decir "Vacuuming done, freed 0B of archived journals". El orden es primero journalctl --rotate y después journalctl --vacuum-time=7d. Ten en cuenta que el borrado es irreversible, también para las pruebas que justo estabas buscando.
¿Por qué en mi servidor Debian no hay /var/log/syslog?
Porque ese archivo no lo crea systemd, sino un servicio de syslog adicional, normalmente rsyslog. Es un paquete aparte y, en las instalaciones mínimas de Debian 12 y Debian 13, ya no viene incluido, mientras que en las imágenes de servidor de Ubuntu 22.04 y 24.04 sí está presente. Si falta, systemctl status rsyslog responde con "Unit rsyslog.service could not be found." y tail -f /var/log/syslog falla con "tail: cannot open '/var/log/syslog' for reading: No such file or directory". Los mensajes están ahí igualmente, los lees con journalctl, y fail2ban también saca sus eventos del journal.

journalctl systemd Linux Debian Ubuntu Archivos de log Resolución de problemas Administración de servidores