When troubleshooting Linux systems, particularly older distributions like CentOS 5.x, the absence of human-readable timestamps in dmesg output can be frustrating. The kernel ring buffer stores messages with nanosecond precision timestamps, but they're not displayed by default in a format that's immediately useful.
First, let's see what raw dmesg output looks like:
# dmesg
[ 0.000000] Initializing cgroup subsys cpuset
[ 0.000000] Initializing cgroup subsys cpu
[ 0.000000] Linux version 2.6.18-398.el5 (mockbuild@builder10.centos.org) (gcc version 4.1.2 20080704 (Red Hat 4.1.2-55)) #1 SMP Tue Mar 3 15:19:22 EST 2015
The secret lies in understanding that the numbers in brackets are seconds since boot. Here's a practical awk solution to convert them:
# dmesg | awk -F'[][]' '{ printf("[%s] %s\n", strftime("%F %T", systime() - (procinfo["uptime"] - $2)), $0) }'
For those who prefer Perl, here's another approach:
# dmesg | perl -ne 'BEGIN { $uptime = cat /proc/uptime =~ /^(\d+)/ }; /^$$\s*(\d+\.\d+)$$/ and printf "[%s] %s", scalar(localtime(time - $uptime + $1)), $_;'
For a more permanent solution, you can configure rsyslog to capture kernel messages with timestamps:
# Add to /etc/rsyslog.conf
kern.* /var/log/kern.log
# Then restart the service
service rsyslog restart
For frequent use, add this to your .bashrc:
alias dmesg-time='dmesg | awk -F\"] \" '\''{ printf("[%s] %s\n", strftime("%F %T", systime() - (procfs["uptime"] - $1)), $0) }'\'
Remember that CentOS 5.x uses an older 2.6 kernel with some limitations:
- The timestamp precision is in seconds (not nanoseconds like newer kernels)
- Some dmesg options available in newer versions won't work
- Consider upgrading if timestamp precision is critical for your use case
Here's what the converted output looks like:
[2023-04-15 14:30:22] [ 0.000000] Initializing cgroup subsys cpuset
[2023-04-15 14:30:22] [ 0.000000] Initializing cgroup subsys cpu
[2023-04-15 14:30:22] [ 0.000000] Linux version 2.6.18-398.el5
When debugging kernel messages on CentOS 5.x systems, the default dmesg
output doesn't include human-readable timestamps. This makes it challenging to correlate events with other system logs. The timestamps exist internally but aren't displayed by default in this older CentOS version.
First verify your current dmesg
output format:
$ dmesg | head -5
You'll typically see raw output without timestamps:
eth0: no IPv6 routers present
sd 0:0:0:0: [sda] Assuming drive cache: write through
For CentOS 5.x, use the -T
flag (requires util-linux package v2.20 or later):
$ dmesg -T
If -T
isn't available, use this alternative:
$ dmesg | while read line; do echo "[$(date -d"${line%%]*}" "+%F %T")]${line#*]}"; done
Example output with timestamps:
[2023-11-15 14:30:22] eth0: no IPv6 routers present
[2023-11-15 14:30:23] sd 0:0:0:0: [sda] Assuming drive cache: write through
To make timestamps permanent, modify the kernel boot parameters:
$ echo 'options printk time=1' >> /etc/modprobe.conf
$ reboot
For systems with systemd (though rare in CentOS 5.x):
$ journalctl -k --since "1 hour ago"
For advanced parsing, create a timestamp conversion script:
#!/bin/bash
dmesg | awk -F'[][]' '{printf "[%s]%s\n", strftime("%F %T", $2), $3}'
- The kernel stores timestamps as seconds since boot
- Older util-linux packages might not support
-T
flag - Consider upgrading to newer CentOS if frequently needing this feature