Consulta básica de logs del sistema con journalctl en sistemas Systemd

La fecha de los logs es en base a la hora local configurada, para poder consultar la hora configurada, zona y otras opciones se puede ejecutar el comando timedatectl.

timedatectl status
# timedatectl list-timezones     # Listas las zonas horarios disponibles.
# timedatectl set-timezone zone  # Permite fijar una zona horario en concreto.

Depende de la distribución en uso, es posible que no se guarden en disco los logs de systemd. Si se quieren tener los logs disponibles tras un reinicio simplemente se debe crear el directorio /var/log/journal y configurar en journald.conf el tamaño del log máximo deseado.

mkdir /var/log/journal
echo "SystemMaxUse=25M" >> /etc/systemd/journald.conf
systemctl restart systemd-journald 

Usos horarios disponibles / uso horario en uso / fijar un nuevo uso horario para los logs.

timedatectl list-timezones
timedatectl status
timedatectl set-timezone Europe/Berlin

Acceder a todos los registros del sistema (similar al anterior cat /var/log/messages). Para salir “q”.

journalctl

Mostrar logs en UTC

journalctl --utc

Equivalencias con Syslog a la hora de consultar logs en systemd con journalctl. ( Facility_levels)

journalctl -l SYSLOG_FACILITY=10 # Equivaldría a auth.log
# Qué usuarios y cuando han ejecutado el comando "su" desde ayer. 
journalctl --since 'yesterday' -l SYSLOG_FACILITY=4 | grep -i su
abr 25 03:46:42 cacotaspc su[9027]: (to root) busi on pts/1
abr 25 17:50:44 cacotaspc su[788]: (to root) espinete on pts/0
abr 26 00:49:23 cacotaspc su[22878]: (to root) onemi on pts/1

Mostrar mensajes de log en tiempo real.

journalctl -f

Ver la lista de todos los arranques del sistema de forma ordenada.

journalctl --list-boots

Mostrar los logs del boot actual o de una fecha concreta (También por ID).

journalctl -b
journalctl -b 231
journalctl _BOOT_ID=6f943d5a532043469fdbd19f5f81b6ae

Ver los mensajes del kernel.

journalctl -k
# Ver los mensajes del kernel de hoy.	
journalctl -k -b

Filtrar por identificador syslog

Hay logs de journal que no están accesibles a través de unidades, como por ejemplo el kernel o aplicaciones como su/sudo, login, mount, etc. En al salida de journal, el tercer campo suele referirse al identificador syslog del servicio y puede filtrarse usando “-t”

journal -t kernel

NOTA: En algunos casos las unidades tienen también un identificador syslog, y por lo tanto se puede usar “-t” para mostrarlos. Aunque estos suelen encontrarse también al visualizar los logs filtrando por unidad von “-u”. El identificador syslog puede ser definido mediante la opción “SyslogIdentifier” en ficheros service.

Filtrar por número de entradas en el registro de logs. (10 mensajes si no se especifica una cifra).

journalctl -n

Filtras los logs por ejecutables / programas / usuario.

# Indicando el nombre	
journalctl _COMM=NetworkManager
# Especificando la ruta
journalctl /usr/sbin/NetworkManager
# Utilizando grep
journalctl | grep NetworkManager

Mostrar el Log de un determinado programa en ejecución mediante el PID.

journalctl _PID=307

Mostrar logs por usuario.

journalctl _UID=100

Conocer más journal fields para usar como filtro.

man systemd.journal-fields

Filtrar la salida por servicios de systemd.

# Para ver todos los servicios de Systemd: systemctl list-units -t service --all
# Especificar un servicio systemd en concreto.
journalctl -u dbus.service
# Buscar varios servicios  añadiendo el caracter “+” (equivale a un “or”).
journalctl _SYSTEMD_UNIT=apparmor.service + _SYSTEMD_UNIT=dbus.service

Filtrar por fechas.

Se utilizan los parámetros “--since” y “--until”, así como expresiones tipo “yesterday”, “ago” o “today”. El formato de tiempo es habitualmente YYYY-MM-DD HH:MM:SS.

# Ver los logs desde el día de ayer hasta hoy a las 02:00 horas.
journalctl --since 'yesterday' --until '02:00'
 
# Mostrar nuevos logs desde ahora y durante 10 segundos.
journalctl -f --until +10 
 
# Especificar un intervalo de fechas.	
journalctl --since='2015-02-29 00:01' --until='2015-03-29 00:01'
 
# Todos los logs especificando la fecha en el formato que os comentaba anteriormente, y filtrando por el programa firefox
journalctl _COMM=firefox --since='2015-02-29 00:01' --until='2015-03-29 00:01'
 
# Lo mismo que el caso anterior pero en este caso filtrando por el servicio de sshd.service
journalctl -u sshd.service --since='2015-02-29 00:01' --until='2015-03-29 00:01'
 
# Ver lo que ha pasado en la última media hora:
journalctl --since '30 min ago'

Filtrar por la prioridad del mensaje.

journalctl -p 2
# Filtrando únicamente problemas en el kernel.
journalctl -t kernel -p 4

Los mensajes se clasifican en función de su prioridad en 7 niveles diferentes.

NOTA: Estas opciones son muy útiles a la hora de filtrar logs del kernel con problemas, de no especificar ninguna el nivel 7 (debug) es el estándar (contiene todos los niveles, el 0 al 7). Por ejemplo el nivel 4 mostrará los logs “emerg”, “alert”, “crit” y “error”.

Mensajes de los discos duros u otros dispositivos de bloque. (Útil a la hora de buscar problemas.)

journalctl /dev/sdX

Consultar el espacio que están ocupando los diferentes logs.

# Configurable en /etc/systemd/journald.conf con "SystemMaxUse=50M" (Por defecto usa el 10% del sistema de ficheros como máximo).
journalctl --disk-usage

Reduce el tamaño de logs a 1Gbyte eliminando para ello los registros más antiguos.

journalctl --vacuum-size=1G

Guardará únicamente los logs desde el último año.

journalctl --vacuum-time=1years

Formatos de salida para los logs con systemd

journalctl -b -u httpd2 -o json-pretty

Enviar logs a journalctl (Systemd)

Escribiendo en los logs de systemd de manera nativa con C y Python.

#include <systemd/sd-journal.h>
 
int main(int argc, char *argv[]) {
        sd_journal_print(LOG_NOTICE, "Hola Mundo!");
        return 0;
}

Ejemplo de código python escribiendo logs para journalctl.

from systemd import journal
journal.send('Hola Mundo!')

Bindings para usar login con journalctl.

Si se tiene algún servicio configurado en systemd que utilice la función “printf()”, las cadenas escritas también pasarán directamente al registro journalctl automáticamente.

#include <stdio.h>
 
int main(int argc, char *argv[]) {
        printf("Hola Mundo!\n");
        return 0;
}

Desde systemd 216 en Agosto del 2014 y de manera predeterminada, journalctl trae una opción “Forward” activada que intercepta automáticamente los logs de syslog / rsyslog / syslog-ng / etc.

Ejemplo enviando en código C un mensaje a Syslog.

#include <syslog.h>
 
int main(int argc, char *argv[]) {
        syslog(LOG_NOTICE, "Hola Mundo!");
        return 0;
}

Para registrar logs de aplicaciones sin soporte journalctl nativo, se puede intentar que envíen logs por la salida estándar, que utilicen syslog o bien systemd-cat (uso de scripts mayormente).

Escribiendo en los logs de journalctl con systemd-cat.

echo 'XXX' | systemd-cat
echo 'XXX' | systemd-cat -p info
echo 'XXX' | systemd-cat -p warning
echo 'XXX' | systemd-cat -p emerg

Configurar logs error y access de Nginx en journalctl.

server {
    # error_log stderr; # También funcionaría. Pero access_log no soporta stderr.
    error_log syslog:server=unix:/dev/log;
    access_log syslog:server=unix:/dev/log;
    ...
}

Arrancar / Recargar / Parar / Reiniciar servicios con systemd y conocer el resultado de la operación

A diferencia de los antiguos sistemas SysV, cuando se trabaja con systemd, al realizar acciones sobre servicios a través de systemctl no se obtiene ninguna salida si el comando fue exitoso. En los casos en que se quiera obtener algo de información, se puede hacer uso de una tubería con el comando “journalctl”. Veamos un ejemplo al recargar la configuración de SSHD.

systemctl stop sshd && journalctl -fxu sshd
 
Jan 19 22:09:34 proxy sshd[110]: Received SIGHUP; restarting.
Jan 19 22:09:34 proxy sshd[110]: Set /proc/self/oom_score_adj to 0
Jan 19 22:09:34 proxy sshd[110]: Set /proc/self/oom_score_adj from 0 to -1000
Jan 19 22:09:34 proxy sshd[110]: Server listening on 0.0.0.0 port 22.
Jan 19 22:09:34 proxy sshd[110]: Server listening on :: port 22.
Jan 19 22:09:34 proxy systemd[1]: Reloaded OpenSSH server daemon.
-- Subject: Unit sshd.service has finished reloading its configuration
-- Defined-By: systemd
-- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
-- 
-- Unit sshd.service has finished reloading its configuration
-- 
-- The result is done.

Enlaces de interés: http://0pointer.de/blog/projects/journal-submit.html