Converting dmesg Timestamps to Human-Readable Time in Linux: A Practical Guide


2 views

The timestamp format [600711.395348] in dmesg output represents:

  • Seconds since boot: The number before the decimal (600711) shows seconds since system startup
  • Microseconds: The decimal portion (395348) represents microseconds

Method 1: Using date command

# Get system boot time
boot_time=$(date -d "$(uptime -s)" +%s)

# Calculate real time
dmesg_time="600711.395348"
seconds=${dmesg_time%%.*}
microseconds=${dmesg_time##*.}

# Convert to human-readable format
date -d "@$((boot_time + seconds))" "+%Y-%m-%d %H:%M:%S.${microseconds}"

Method 2: Perl one-liner

dmesg | perl -ne 'BEGIN { $boot_time = date -d "\$(uptime -s)" +%s; chomp($boot_time) }
    if (/^$$(\d+)\.(\d+)$$/) {
        $time = $boot_time + $1;
        $micro = $2;
        print date -d \@$time "+%Y-%m-%d %H:%M:%S.$micro";
        print $_;
    }'

Method 3: Python script

#!/usr/bin/env python3
import sys
import subprocess
from datetime import datetime

def get_boot_time():
    cmd = "uptime -s"
    boot_str = subprocess.check_output(cmd, shell=True).decode().strip()
    return datetime.strptime(boot_str, "%Y-%m-%d %H:%M:%S")

boot_time = get_boot_time()

for line in sys.stdin:
    if line.startswith('['):
        try:
            timestamp, rest = line[1:].split(']', 1)
            seconds, microseconds = timestamp.split('.')
            delta = float(seconds) + float(microseconds)/1e6
            event_time = boot_time + timedelta(seconds=delta)
            print(f"[{event_time.strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]}] {rest.strip()}")
        except ValueError:
            print(line.strip())

Example 1: Convert specific dmesg entry

echo "[600711.395348] do_trap: 6 callbacks suppressed" | \
awk '{print $1}' | tr -d '[]' | \
xargs -I{} date -d "@$(($(date -d "$(uptime -s)" +%s) + {%.*}))" "+%Y-%m-%d %H:%M:%S.${1#*.}"
  • systemd-analyze: systemd-analyze timestamp $(echo "600711.395348" | cut -d'[' -f2 | cut -d']' -f1)
  • journalctl: journalctl --boot | grep "do_trap" (shows human-readable timestamps)

For processing large dmesg logs, the Python method is generally fastest. The one-liners are convenient for quick conversions but may be slower for bulk processing.


The timestamp format in dmesg output represents seconds and microseconds since system boot. For example:

[600711.395348] do_trap: 6 callbacks suppressed

Here, 600711.395348 means the event occurred 600,711.395348 seconds after boot.

The simplest solution is using dmesg's built-in conversion:

dmesg --time-format ctime

This will display timestamps in human-readable format like:

[Mon Oct 23 14:30:45 2023] do_trap: 6 callbacks suppressed

When you need more precise control, you can calculate it manually:

# Get system boot time
boot_time=$(date -d "$(uptime -s)" +%s)

# Convert dmesg timestamp
dmesg_timestamp="600711.395348"
seconds=${dmesg_timestamp%.*}
microseconds=${dmesg_timestamp#*.}

# Calculate real time
real_time=$((boot_time + seconds))
formatted_time=$(date -d "@$real_time" +"%Y-%m-%d %H:%M:%S")

echo "$formatted_time.${microseconds:0:6}"

For processing multiple entries, here's a Python solution:

#!/usr/bin/env python3
import re
import datetime
import subprocess

def get_boot_time():
    uptime_output = subprocess.check_output(['uptime', '-s']).decode().strip()
    return datetime.datetime.strptime(uptime_output, "%Y-%m-%d %H:%M:%S")

def convert_dmesg_time(line, boot_time):
    match = re.match(r'$$(\d+\.\d+)$$', line)
    if match:
        timestamp = float(match.group(1))
        event_time = boot_time + datetime.timedelta(seconds=timestamp)
        return line.replace(match.group(0), f"[{event_time.strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]}]")
    return line

boot_time = get_boot_time()
with open('dmesg.log') as f:
    for line in f:
        print(convert_dmesg_time(line.strip(), boot_time))

Remember that these conversions use UTC by default. To show local time:

dmesg --time-format ctime | TZ=$(cat /etc/timezone) awk '{print $0}'

To make human-readable timestamps permanent:

# Add to /etc/sysctl.conf
kernel.printk_time = 1