Leer registros con journalctl
Módulo 6: Servicios y registros · Tiempo de lectura: 11 minutos
Objetivo de aprendizaje: Tras esta lección, podrá buscar de forma específica en los registros de su servidor con journalctl (por servicio, prioridad y tiempo), sabrá dónde se encuentran otros archivos de registro y evitará que los registros llenen su disco.
Conceptos clave: journald, journal, journalctl -u, -p, --since/--until, -f, -b, -e, -n, prioridad (err, warning, info), almacenamiento persistente, /var/log/journal, --disk-usage, --vacuum-size, /var/log, logrotate, rsyslog
El registro como primer testigo
Cuando algo no funciona en su servidor, el motivo casi siempre figura en un registro. Un sitio web que muestra una página de error, un servicio que no arranca, una copia de seguridad que no se ejecutó anoche: el servidor lo ha anotado. Un buen administrador consulta primero el registro y solo después empieza a cambiar cosas.
En los servidores Linux modernos, journald (parte de systemd) reúne los mensajes del kernel, del propio systemd y de todos los servicios en un único registro: el journal. Se lee con journalctl.
Para poder leerlo todo, debe pertenecer al grupo adm o systemd-journal, o bien usar sudo. Sin esos permisos solo verá sus propios mensajes.
¿Dónde se guarda? Persistente o volátil
journald guarda el journal en uno de dos lugares:
- en
/var/log/journal/: persistente, los registros se conservan tras un reinicio; - en
/run/log/journal/: volátil, en memoria, se pierde tras un reinicio.
La configuración predeterminada (Storage=auto en /etc/systemd/journald.conf) elige el modo persistente si existe el directorio /var/log/journal/. En Debian, el paquete systemd crea ese directorio desde Debian 11, y en Ubuntu también existe. Compruébelo:
anna@web1:~$ ls -d /var/log/journal
/var/log/journal
anna@web1:~$ journalctl --list-boots | tail -n 3
-2 3c1f... Sun 2026-11-01 04:30:12 CET Sun 2026-11-08 04:30:01 CET
-1 9ab7... Sun 2026-11-08 04:30:40 CET Mon 2026-11-09 08:12:05 CET
0 e41d... Mon 2026-11-09 08:12:30 CET Mon 2026-11-09 11:40:17 CETSi solo ve un arranque aunque el servidor ya se haya reiniciado alguna vez, sus registros son volátiles. Cree el directorio (sudo mkdir -p /var/log/journal y sudo systemd-tmpfiles --create --prefix /var/log/journal) y reinicie journald. Es importante: después de un fallo, lo que quiere saber precisamente es qué ocurrió antes del reinicio.
Desde Debian 12, Debian ya no instala rsyslog de forma predeterminada. Ese programa escribía antes archivos de texto como /var/log/syslog y /var/log/auth.log. Por tanto, en un servidor Debian nuevo no existen; todo está en el journal. Ubuntu sigue incluyendo rsyslog. Las guías que dicen "consulte /var/log/auth.log" puede traducirlas en Debian a journalctl -u ssh.
Buscar: los filtros que de verdad usará
Sin filtro, journalctl lo muestra todo, empezando por lo más antiguo. Rara vez es lo que busca. Los filtros más importantes, que puede combinar:
| Filtro | Ejemplo | Qué hace |
|---|---|---|
-u <unit> | journalctl -u nginx | solo ese servicio |
-p <prioriteit> | journalctl -p err | solo errores y lo más grave |
--since, --until | --since "2026-11-09 03:00" --until "04:00" | periodo de tiempo; también today, yesterday, "1 hour ago" |
-b | journalctl -b, journalctl -b -1 | desde este arranque, o el anterior |
-f | journalctl -u nginx -f | seguir en directo (como tail -f), detener con Ctrl+C |
-e | journalctl -u ssh -e | saltar al final |
-n | journalctl -u ssh -n 50 | las últimas 50 líneas |
-k | journalctl -k | solo mensajes del kernel |
--no-pager | sin paginar, práctico con grep |
Las prioridades van de 0 (emerg) a 7 (debug): emerg, alert, crit, err, warning, notice, info, debug. Con -p err obtiene err y todo lo que sea más grave. -p warning muestra también las advertencias.
Un recorrido de búsqueda típico. Desde esta mañana, su sitio web devuelve un error 502:
anna@web1:~$ systemctl status php8.4-fpm
× php8.4-fpm.service - The PHP 8.4 FastCGI Process Manager
Active: failed (Result: exit-code) since Mon 2026-11-09 07:02:11 CET; 4h ago
...
anna@web1:~$ sudo journalctl -u php8.4-fpm --since today -p warning --no-pager
nov 09 07:02:10 web1 php-fpm8.4[1830]: [09-Nov-2026 07:02:10] ERROR: [/etc/php/8.4/fpm/pool.d/www.conf:42] unknown entry 'pm.max_children '
nov 09 07:02:10 web1 php-fpm8.4[1830]: [09-Nov-2026 07:02:10] ERROR: FPM initialization failed
nov 09 07:02:11 web1 systemd[1]: php8.4-fpm.service: Main process exited, code=exited, status=78/CONFIG
nov 09 07:02:11 web1 systemd[1]: php8.4-fpm.service: Failed with result 'exit-code'.La causa aparece literalmente: un error tipográfico en la línea 42 de un archivo de configuración. El estado 78 (CONFIG) confirma que se trata de un error de configuración. No tiene que adivinar nada.
Dos consejos para la lectura:
- Lea de arriba abajo y busque el primer error. Un error suele provocar toda una serie de mensajes derivados. El primero suele ser la causa.
- Fíjese en la hora. ¿Qué cambió en torno a ese momento? ¿Una actualización automática (lección 4.2:
/var/log/unattended-upgrades/), un cambio suyo, un reinicio?
Otros archivos de registro
No todo está en el journal. Muchos programas escriben también (o únicamente) sus propios archivos en /var/log/:
| Archivo o directorio | Qué contiene |
|---|---|
/var/log/nginx/access.log y error.log | cada petición y cada error de nginx |
/var/log/apt/history.log | qué instaló apt y cuándo |
/var/log/unattended-upgrades/ | actualizaciones automáticas (lección 4.2) |
/var/log/fail2ban.log | bloqueos (lección 5.3) |
/var/log/mysql/ o el journal | MariaDB/MySQL, según la configuración |
Los archivos de texto grandes se leen con less (buscar con /), el final con tail -n 50, en directo con tail -f, y se filtran con grep:
anna@web1:~$ sudo grep " 502 " /var/log/nginx/access.log | tail -n 5Los registros de los contenedores Docker no están en /var/log, sino en el propio Docker: docker compose logs (lección 9.3).
Los registros no deben llenar su disco
Un disco lleno es una de las causas más frecuentes de que un servidor deje de funcionar "de repente": las bases de datos se detienen, las actualizaciones fallan y a veces ni siquiera puede iniciar sesión. Los registros suelen ser los culpables.
El journal se limita a sí mismo. De forma predeterminada utiliza como máximo el 10% del sistema de archivos, con un tope de 4 GB (SystemMaxUse=). Cuánto ocupa ahora y cómo hacer limpieza:
anna@web1:~$ journalctl --disk-usage
Archived and active journals take up 512.0M in the file system.
anna@web1:~$ sudo journalctl --vacuum-time=30d # elimina lo que tenga más de 30 días
anna@web1:~$ sudo journalctl --vacuum-size=500M # hasta 500 MBSi quiere un límite fijo, indíquelo en un archivo drop-in /etc/systemd/journald.conf.d/grootte.conf:
[Journal]
SystemMaxUse=1Gy reinicie journald con sudo systemctl restart systemd-journald.
Los archivos de texto de /var/log los gestiona logrotate: cada día o cada semana se renombra un archivo (error.log.1), las versiones más antiguas se comprimen (.gz) y las más viejas se eliminan. Las reglas de cada programa están en /etc/logrotate.d/. Los paquetes de la distribución traen su propia regla. Si un programa o script propio escribe en su propio archivo de registro, cree usted mismo una regla; de lo contrario, el archivo crecerá sin fin.
Buscar qué ocupa espacio:
anna@web1:~$ df -h /
anna@web1:~$ sudo du -xh /var/log | sort -h | tail -n 5Registros y privacidad
Los registros contienen direcciones IP, nombres de usuario y a veces direcciones de correo electrónico: son datos personales. No los conserve más tiempo del necesario (entre unas semanas y unos meses es lo habitual en un servidor pequeño), no los deje accesibles públicamente (un directorio /logs dentro de su webroot es un error conocido) y no los copie sin más a servicios de terceros.
En AlmaLinux y Rocky Linux
journalctl funciona igual. Allí rsyslog sigue activado de forma predeterminada, con archivos como /var/log/messages y /var/log/secure (el equivalente de auth.log). Los mensajes de SELinux están en /var/log/audit/audit.log; ausearch -m avc -ts recent muestra los rechazos recientes.
Resumen
- journald reúne todos los mensajes en el journal; léalo con
journalctl, filtrando por servicio (-u), prioridad (-p), tiempo (--since) y arranque (-b). - Compruebe que el journal es persistente (que existe
/var/log/journal); de lo contrario, perderá sus registros tras un reinicio. - Debian 12 y posteriores no incluyen rsyslog de forma predeterminada y, por tanto, tampoco
/var/log/auth.logni/var/log/syslog; todo está en el journal. - Busque el primer error y observe qué cambió en torno a ese momento.
- Vigile el tamaño: el journal se limita a sí mismo (
--disk-usage,--vacuum-*) y logrotate se encarga de los archivos de texto.
Cuestionario
Ejercicio
Ejercicio Z6.2: Analizar un servicio que se bloquea. El archivo de ejemplo journal-crash-1.txt contiene la salida de systemctl status y journalctl de un servicio que se reinicia una y otra vez y luego se rinde. Responda: ¿cómo se llama el servicio, cuántas veces intentó systemd iniciarlo, con qué código de salida se detuvo, cuál es la causa según el primer mensaje de error y a qué hora se rindió systemd? El programa compara sus respuestas con la clave fija. Después, compruebe en su propio servidor si journalctl -p err -b muestra errores y si su journal es persistente.
Para saber más
- Manual de
journalctl(1): https://manpages.debian.org/trixie/systemd/journalctl.1.en.html - Manual de
journald.conf(5)(Storage=, SystemMaxUse=): https://manpages.debian.org/trixie/systemd/journald.conf.5.en.html - Debian 12, notas de la versión 5.1.7 (rsyslog ya no viene de forma predeterminada): https://www.debian.org/releases/bookworm/amd64/release-notes/ch-information.en.html
