Today I was asked by a colleague how to display a human readable timestamp for the output of dmesg. Indeed on some Linux distributions or old Linux systems, dmesg’s output will have something like:
[57494.681117] perf: interrupt took too long (2502 > 2500), lowering kernel.perf_event_max_sample_rate to 79000
[87459.446474] perf: interrupt took too long (3152 > 3127), lowering kernel.perf_event_max_sample_rate to 63000
[130155.365248] perf: interrupt took too long (3942 > 3940), lowering kernel.perf_event_max_sample_rate to 50000
[173558.997403] perf: interrupt took too long (5166 > 4927), lowering kernel.perf_event_max_sample_rate to 38000
[282743.690763] perf: interrupt took too long (6469 > 6457), lowering kernel.perf_event_max_sample_rate to 30000
[396297.129251] device-mapper: uevent: version 1.0.3
[396297.129458] device-mapper: ioctl: 4.37.0-ioctl (2017-09-20) initialised: dm-devel@redhat.com
[396299.641819] nr_pdflush_threads exported in /proc is scheduled for removal
[445881.822812] TCP: ens192: Driver has suspect GRO implementation, TCP performance may be compromised.
[561098.497053] perf: interrupt took too long (8113 > 8086), lowering kernel.perf_event_max_sample_rate to 24000
On my Oracle Linux 7 system, without any options, the timestamp is just a string of numbers, but I can use options “-T” or “-e” or “-H” to display time and delta in human readable format. However on his Oracle Linux 6 system, there is no such options for dmesg.
Fortunately a simple bash script will give what he needs:
#!/bin/bash
date_format="%a %b %d %T %Y"
uptime=$(cut -d " " -f 1 /proc/uptime)
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 "Timestamp is not enabled (see /sys/module/printk/parameters/time)"
fi