Guía

Logs en Linux: journalctl, /var/log, rsyslog y logrotate

Actualizado: · Skillaria.Top

En las distribuciones actuales de Linux los logs los recoge journald y se leen con journalctl: journalctl -u nginx muestra los registros de un único servicio, -f sigue el flujo en tiempo real, y --since y -p filtran por hora e importancia. Los logs de texto están en /var/log, los escribe rsyslog o la propia aplicación, y logrotate comprime y elimina periódicamente los archivos antiguos para que el disco no se llene.

Cuando un servicio se cae de noche, la respuesta casi siempre está en los logs; la cuestión es dónde buscarla. En las distribuciones modernas (Ubuntu, Debian, RHEL, Fedora, Arch) los eventos los recoge el servicio journald y se leen con el comando journalctl. Al mismo tiempo, muchos programas escriben archivos de texto normales en /var/log, y logrotate se encarga de que no crezcan sin control. A continuación veremos cómo trabajar con los logs de journalctl en Linux en la práctica, dónde están los demás registros y cómo no perder lo importante durante la rotación.

Dónde se guardan los logs en Linux

Hay tres fuentes, y conviene tenerlas presentes como un mapa:

  • journald — el diario binario de systemd. Recibe stdout y stderr de todos los servicios, los mensajes del núcleo y syslog. Se guarda en /var/log/journal/ (de forma permanente) o en /run/log/journal/ (hasta el reinicio).
  • /var/log — archivos de texto. Los escribe rsyslog (por ejemplo, /var/log/syslog, /var/log/auth.log) o las propias aplicaciones: nginx, PostgreSQL, MySQL.
  • Búfer circular del núcleo — mensajes de los controladores y del hardware; los muestra dmesg o journalctl -k.
ArchivoContenido
/var/log/syslog (Debian/Ubuntu)registro general del sistema
/var/log/messages (RHEL/Fedora)lo mismo en la familia Red Hat
/var/log/auth.log o /var/log/secureinicios de sesión, sudo, SSH
/var/log/kern.logmensajes del núcleo
/var/log/dpkg.log, /var/log/apt/instalación de paquetes
/var/log/nginx/access.log y error.log del servidor web
/var/log/wtmp, /var/log/btmpregistros binarios de inicios de sesión, se leen con last y lastb

La mayoría de los archivos de /var/log solo son accesibles para root o para el grupo adm, por eso los comandos de lectura a menudo deben ejecutarse con sudo.

journalctl: comandos básicos

Sin argumentos, journalctl muestra el diario completo, desde los registros más antiguos, a través del paginador less. Rara vez es lo que se necesita: normalmente se reduce la selección enseguida.

journalctl              # todo el diario, de más antiguo a más reciente
journalctl -e           # abrir directamente al final
journalctl -n 50        # las últimas 50 líneas
journalctl -r           # en orden inverso, lo más nuevo arriba
journalctl --no-pager   # sin less; útil en scripts y con grep

Dentro del paginador funcionan las teclas habituales de less: / para buscar, G para ir al final y q para salir. Las líneas largas se cortan según el ancho de la pantalla; las flechas izquierda y derecha las desplazan.

Logs de un servicio concreto: journalctl -u

El caso más frecuente es ver lo que escribió una unidad de systemd. No hace falta buscar el archivo ni filtrar con grep:

$ sudo journalctl -u nginx -n 20
Oct 14 03:12:41 web1 systemd[1]: Starting nginx.service - A high performance web server...
Oct 14 03:12:41 web1 nginx[1834]: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
Oct 14 03:12:41 web1 systemd[1]: nginx.service: Control process exited, code=exited, status=1/FAILURE
Oct 14 03:12:41 web1 systemd[1]: nginx.service: Failed with result 'exit-code'.

El flag -u puede repetirse: journalctl -u nginx -u php8.2-fpm muestra ambos servicios mezclados por hora, lo cual resulta cómodo cuando el error aparece en la frontera entre los dos. Para las unidades de usuario (systemctl --user) use journalctl --user -u nombre.

Logs en tiempo real: journalctl -f

sudo journalctl -u nginx -f

Es el equivalente de tail -f: muestra las últimas 10 entradas y espera las nuevas. Resulta útil tenerlo en otra terminal mientras reinicia el servicio o reproduce el error. Para salir, pulse Ctrl+C.

Filtros por tiempo y por arranque

Si sabe cuándo ocurrió la avería, la selección por tiempo se hace con --since y --until. Aceptan tanto fechas exactas como valores relativos:

journalctl --since "2026-10-14 02:50" --until "2026-10-14 03:30"
journalctl --since "1 hour ago"
journalctl --since yesterday --until today
journalctl -u nginx --since "10 min ago"

El segundo corte útil es por arranques del sistema. Si el servidor se reinició solo, la causa suele estar al final de la sesión anterior:

$ journalctl --list-boots
 -2 8f1c...  Sat 2026-10-12 09:01:12 UTC  Sun 2026-10-13 22:47:03 UTC
 -1 a7d2...  Sun 2026-10-13 22:48:30 UTC  Tue 2026-10-14 03:05:51 UTC
  0 c3e9...  Tue 2026-10-14 03:07:02 UTC  Tue 2026-10-14 09:15:40 UTC

$ journalctl -b -1 -e      # final del arranque anterior
$ journalctl -b            # solo el arranque actual

La lista de arranques solo está disponible si el diario se guarda en disco. Cómo activarlo se explica más abajo, en la sección sobre la configuración de journald.

Filtro por importancia: journalctl -p

Cada entrada tiene una prioridad de syslog del 0 al 7. El flag -p muestra el nivel indicado y todos los más importantes:

CódigoNombreCuándo se usa
0emergel sistema no funciona
1alertse necesita intervención inmediata
2criterror crítico
3errerror
4warningadvertencia
5noticeevento significativo pero normal
6infomensaje informativo
7debugdepuración
journalctl -p err -b              # todos los errores desde el arranque
journalctl -p warning..err -u ssh # rango de niveles para un servicio

El comando journalctl -p err -b es una buena primera comprobación tras reiniciar o actualizar: en unos segundos muestra qué ha salido mal.

Búsqueda y otros filtros

El diario guarda campos estructurados en cada entrada, y por ellos se puede filtrar sin grep:

journalctl _PID=1834                 # por número de proceso
journalctl _COMM=sshd                # por nombre del programa
journalctl _UID=1000                 # por usuario
journalctl /usr/sbin/sshd            # por la ruta del ejecutable
journalctl -k                        # solo mensajes del núcleo (como dmesg)
journalctl -t CRON                   # por identificador de syslog
journalctl -g "Out of memory"        # búsqueda por texto, con expresión regular

El flag -g (--grep) apareció en systemd 237; en sistemas más antiguos use la tubería habitual journalctl --no-pager | grep .... Los filtros por distintos campos se combinan con «Y», así que journalctl -u nginx -p err --since today devuelve solo los errores de nginx de hoy.

Formatos de salida

El flag -o cambia el formato. Las variantes más útiles:

  • -o short-iso — hora en formato ISO 8601, cómodo para comparar con los logs de la aplicación.
  • -o verbose — todos los campos de la entrada, incluidos _SYSTEMD_UNIT, _PID y _BOOT_ID.
  • -o json o json-pretty — para procesarlo con un script o con jq.
  • -o cat — solo el texto del mensaje, sin fecha ni host.
journalctl -u myapp -o json --since today | jq -r '.MESSAGE'

Configurar journald: almacenamiento y tamaño

La configuración está en /etc/systemd/journald.conf (es mejor poner las modificaciones en /etc/systemd/journald.conf.d/*.conf). El parámetro principal es Storage:

  • persistent — el diario se escribe en disco, en /var/log/journal, y sobrevive al reinicio.
  • volatile — solo en memoria, en /run/log/journal.
  • auto (por defecto) — en disco si existe el directorio /var/log/journal.

En algunas imágenes mínimas ese directorio no existe y el historial desaparece tras el reinicio. Para activar el almacenamiento permanente:

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

Para que el diario no ocupe todo el disco, establezca límites:

# /etc/systemd/journald.conf.d/size.conf
[Journal]
Storage=persistent
SystemMaxUse=500M
MaxRetentionSec=1month

Por defecto, SystemMaxUse es el 10 % del tamaño del sistema de archivos, pero no más de 4 GB.

Cómo limpiar el diario de journalctl

$ journalctl --disk-usage
Archived and active journals take up 1.8G in the file system.

sudo journalctl --vacuum-size=300M   # dejar como máximo 300 MB
sudo journalctl --vacuum-time=2weeks # eliminar entradas de más de dos semanas
sudo journalctl --rotate             # cerrar los archivos activos para poder borrarlos también

No conviene borrar archivos de /var/log/journal con rm: vacuum hace lo mismo de forma segura y no toca el archivo activo.

rsyslog: los logs de texto clásicos

rsyslog es el demonio que recibe mensajes de syslog (también los reenviados desde journald) y los distribuye en archivos según reglas. La configuración está en /etc/rsyslog.conf y /etc/rsyslog.d/*.conf. Una regla consta de un selector origen.nivel y una acción:

# /etc/rsyslog.d/50-default.conf (fragmento)
auth,authpriv.*        /var/log/auth.log
*.*;auth,authpriv.none -/var/log/syslog
kern.*                 -/var/log/kern.log

El guion delante de la ruta significa que no se sincroniza el archivo con el disco tras cada línea: es más rápido, pero en caso de avería pueden perderse las últimas líneas. Después de cambiar la configuración, compruebe la sintaxis y reinicie el servicio:

sudo rsyslogd -N1
sudo systemctl restart rsyslog

La razón principal para mantener rsyslog junto a journald es reenviar los logs a un servidor central. Una sola línea envía todo por TCP:

# /etc/rsyslog.d/90-remote.conf
*.* @@logs.example.com:514

Un solo @ significa UDP, y dos @@, TCP. Si el servidor se cae por completo, la copia de los logs queda en otra máquina. Para escribir un mensaje propio en el registro del sistema desde un script, use logger:

logger -t backup -p user.err "La copia de seguridad de la base de datos falló"
journalctl -t backup -n 5

logrotate: rotación de logs

Los logs de texto crecen sin límite hasta que alguien los recorta. Esa tarea la hace logrotate: una vez al día (desde cron o desde el temporizador logrotate.timer) renombra el archivo actual, comprime los antiguos y elimina los más viejos. La configuración general está en /etc/logrotate.conf, y las reglas de cada programa, en /etc/logrotate.d/.

# /etc/logrotate.d/myapp
/var/log/myapp/*.log {
    daily
    rotate 14
    compress
    delaycompress
    missingok
    notifempty
    create 0640 myapp adm
    postrotate
        systemctl reload myapp > /dev/null 2>&1 || true
    endscript
}
DirectivaSignificado
daily / weekly / size 100Mcuándo rotar
rotate 14

Preguntas frecuentes

¿Por qué journalctl muestra solo las entradas del último arranque?

El diario se guarda en memoria (/run/log/journal). Cree el directorio /var/log/journal o establezca Storage=persistent en journald.conf y reinicie systemd-journald.

¿Cómo permitir que un usuario normal lea el diario del sistema sin sudo?

Añádalo al grupo systemd-journal (o adm en Debian y Ubuntu): sudo usermod -aG systemd-journal nombre, y después vuelva a iniciar sesión.

¿Se puede ver el diario de otro sistema, por ejemplo de un disco conectado?

Sí, indique el directorio del diario con el flag -D: journalctl -D /mnt/var/log/journal. El flag --file lee un archivo .journal concreto.

¿Hace falta rsyslog si ya existe journald?

No necesariamente. Es útil si se necesitan archivos de texto para herramientas antiguas o para reenviar los logs a un servidor central; en muchas imágenes mínimas ya no se instala.

¿Cómo exportar los logs de un servicio a un archivo para enviárselos a un compañero?

Ejecute journalctl -u nombre --since today --no-pager > service.log: se obtiene un archivo de texto normal.

Aprende este tema en vídeo

Este tema se explica a fondo y con práctica en el curso «Linux: с нуля до уверенного администрирования».

Ir al curso