systemd: ver logs con journalctl

Con systemd existe una gestión centralizada de logs de servicio y kernel a través de la herramienta journalctl. Esta herramienta almacena e indexa todos estos logs para permitir al administrador del sistema gestionarlos desde un único punto.

La forma más básica de ejecutar el comando es directamente sin argumentos (puede que necesitéis saltar como root o usuario con privilegios para determinadas opciones), lo que presentará los logs genéricos del sistema operativo, es decir, lo que siempre hemos visto desde /var/log/messages o /var/log/syslog:

# journalctl

El formato de salida es el habitual tipo syslog, en ese sentido no hay nada nuevo:

foo@bar:[~]: journalctl 
Hint: You are currently not seeing messages from other users and the system.
      Users in groups 'adm', 'systemd-journal', 'wheel' can see all messages.
      Pass -q to turn off this notice.
-- Logs begin at Tue 2018-08-28 22:49:22 CEST, end at Sat 2019-03-30 09:56:20 CET. --
Aug 28 22:49:22 bar.localdomain systemd[1470]: Reached target Timers.
Aug 28 22:49:22 bar.localdomain systemd[1470]: Starting D-Bus User Message Bus Socket.
Aug 28 22:49:22 bar.localdomain systemd[1470]: Reached target Paths.
Aug 28 22:49:22 bar.localdomain systemd[1470]: Listening on Sound System.
Aug 28 22:49:22 bar.localdomain systemd[1470]: Listening on D-Bus User Message Bus Socket.
Aug 28 22:49:22 bar.localdomain systemd[1470]: Reached target Sockets.
Aug 28 22:49:22 bar.localdomain systemd[1470]: Reached target Basic System.
Aug 28 22:49:22 bar.localdomain systemd[1470]: Starting Sound Service...
Aug 28 22:49:22 bar.localdomain systemd[1470]: Started D-Bus User Message Bus.
Aug 28 22:49:22 bar.localdomain pulseaudio[1478]: N: [pulseaudio] alsa-util.c: Di
[...]

Como podéis observar, aparecen logs desde que hay registros, en este caso, desde agosto. Podemos filtrar por una fecha determinada para evitar tener que paginar hasta el final:

foo@bar:[~]:journalctl --since='2019-01-01 00:00' --until '09:00'
foo@bar:[~]:journalctl --since 'yesterday' --until '00:00'

Por defecto, la salida se muestra con paginación, para deshabilitarla:

foo@bar:[~]: journalctl --no-pager

Un punto importante es saber que la paginación se hace a través del comando less, por lo que todos los atajos de teclado usados en less son válidos en journalctl.

¿Preferís ver primero las entradas de log más recientes? Se puede invertir la salida:

foo@bar:[~]: journalctl -r

¿Cómo sería el equivalente a un tail -f 'log_file'?

foo@bar:[~]: journalctl -f

También se puede limitar el número de entradas de log a mostrar por STDOUT, en el siguiente ejemplo se mostarían 10 entradas de log:

foo@bar:[~]: journalctl -n10

Las opciones de filtrado son muy potentes, pues permiten, además de hacerlo por fecha, filtrar por PID, nombre del programa en ejecución, servicio, UID de usuario, etc. Por supuesto, se pueden combinar entre sí. Aquí algunos ejemplos:

Logs de arranque/boot

foo@bar:[~]: journalctl -b

Logs de kernel

foo@bar:[~]: journalctl -k

Logs de un servicio de SystemD

foo@bar:[~]: journalctl -u sshd.service
foo@bar:[~]: journalctl -f -u apache
foo@bar:[~]: journalctl _SYSTEMD_UNIT=avahi-daemon.service

Logs de un PID específico

foo@bar:[~]: journalctl _PID=11111

Logs de un usuario (UID)

foo@bar:[~]: journalctl _UID=1000

Logs de un programa

foo@bar:[~]: journalctl _COMM=dhclient

Logs en formato JSON

foo@bar:[~]: journalctl -o json-pretty

Logs por prioridad/severidad de syslog

foo@bar:[~]: journalctl -p 2

Combinar varios filtros

foo@bar:[~]: journalctl _SYSTEMD_UNIT=avahi-daemon.service _SYSTEMD_UNIT=dbus.service
foo@bar:[~]: journalctl _SYSTEMD_UNIT=avahi-daemon.service _PID=28097

Se puede utilizar el signo + como un OR lógico:

journalctl _SYSTEMD_UNIT=avahi-daemon.service _PID=28097 + _SYSTEMD_UNIT=dbus.service

Como siempre, os recomiendo echar un vistazo a la página man de journalctl para ver con más detalle todas las posibilidades de la herramienta.