dmesg (diagnostic message, mensajes de diagnóstico) es un comando presente en los sistemas operativos Unix que lista el buffer de mensajes del núcleo. Este buffer contiene una gran variedad de mensajes importantes generados durante el arranque del sistema y durante la depuración de aplicaciones. La información ofrecida por dmesg puede guardarse en el disco duro mediante un demonio de registro, como syslog.
Las opciones para mostrar fecha y hora en dmesg son: -T o bien –ctime
dmesg -T [vie mar 28 20:22:49 2010] r8169 0000:02:00.0 enp2s0: link up [vie mar 28 22:28:03 2010] usb 1-13: new high-speed USB device number 4 using xhci_hcd [vie mar 28 22:28:03 2010] usb-storage 1-13:1.0: USB Mass Storage device detected [vie mar 28 22:28:03 2010] scsi6 : usb-storage 1-13:1.0 [vie mar 28 22:28:03 2010] usbcore: registered new interface driver usb-storage [vie mar 28 22:28:05 2010] scsi 6:0:0:0: Direct-Access Verbatim STORE N GO 5.00 PQ: 0 ANSI: 6 [vie mar 28 22:28:06 2010] sd 6:0:0:0: [sdb] 124846080 512-byte logical blocks: (63.9 GB/59.5 GiB)
Dependiendo de la distribución de GNU/Linux utilizada puede que se tengan desactivados los registros de hora y fecha en dmesg.
cat /sys/module/printk/parameters/time Y
El contenido de ese fichero nos muestra si está activado o no el mostrar fechas en dmesg. Y (activado) y N (Desactivado).
Activar timestamps en dmesg
cat /sys/module/printk/parameters/time N echo 1 >/sys/module/printk/parameters/time cat /sys/module/printk/parameters/time Y echo "hola caracola" >/dev/kmsg dmesg | tail .... [3814526.197336] hola caracola
Para hacer el cambio permanente debemos integrar la opción printk en grub.
printk.time=1
Ejemplo.
menuentry "Arch-no-nouveau-pushed" { linux /archboot/vmlinuz-linux cryptdevice=UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx:files root=/dev/mapper/files gpt printk.time=1 initrd /archboot/initramfs-linux.img }
Para consultar si está o no activada en la actual configuración del kernel.
zcat /proc/config.gz |grep PRINTK
Script en Python: pydmesg
Script en Perl.
#!/usr/bin/perl use strict; use warnings; my @dmesg_new = (); my $dmesg = "/bin/dmesg"; my @dmesg_old = `$dmesg`; my $now = time(); my $uptime = `cat /proc/uptime | cut -d"." -f1`; my $t_now = $now - $uptime; sub format_time { my @time = localtime $_[0]; $time[4]+=1; # Adjust Month $time[5]+=1900; # Adjust Year return sprintf '%4i-%02i-%02i %02i:%02i:%02i', @time[reverse 0..5]; } foreach my $line ( @dmesg_old ) { chomp( $line ); if( $line =~ m/\[\s*(\d+)\.(\d+)\](.*)/i ) { # now - uptime + sekunden my $t_time = format_time( $t_now + $1 ); push( @dmesg_new , "[$t_time] $3" ); } } print join( "\n", @dmesg_new ); print "\n";
Script en Bash.
#!/bin/bash # Translate dmesg timestamps to human readable format # desired date format date_format="%a %b %d %T %Y" # uptime in seconds uptime=$(cut -d " " -f 1 /proc/uptime) # run only if timestamps are enabled if [ "Y" = "$(cat /sys/module/printk/parameters/time)" ]; then dmesg | sed "s/^\[[ ]*\?\([0-9.]*\)\] \(.*\)/\\1 \\2/" | while read timestamp message; do printf "[%s] %s\n" "$(date --date "now - $uptime seconds + $timestamp seconds" +"${date_format}")" "$message" done else echo "Timestamps are disabled (/sys/module/printk/parameters/time)" fi