将dmesg时间戳转换为自定义日期格式

uka*_*nth 101 logging kernel timestamp

我试图理解dmesg时间戳,并发现很难将其转换为更改为Java日期/自定义日期格式.

任何帮助深表感谢.

示例dmesg日志:

[14614.647880] airo(eth1): link lost (missed beacons)
Run Code Online (Sandbox Code Playgroud)

谢谢!

小智 161

理解dmesg时间戳非常简单:它是内核启动后的几秒钟.因此,有了启动时间(uptime),您可以添加秒数并以您喜欢的任何格式显示它们.

或者更好,您可以使用该-T选项并解析人类可读的格式.

手册页:

-T, --ctime
    Print human readable timestamps. The timestamp could be inaccurate!

    The time source used for the logs is not updated after system SUSPEND/RESUME.
Run Code Online (Sandbox Code Playgroud)

  • 什么命令接受-T?我的dmesg没有,manpage也没有告诉它.(Linux Mint Debian Edition). (10认同)
  • 根据发行说明,该选项出现在`util-linux 2.20`中:ftp://ftp.kernel.org/pub/linux/utils/util-linux/v2.20/v2.20-ReleaseNotes (7认同)
  • 不适用于redhat和/或oracle linux 5.6,`rpm -qf/bin/dmesg => util-linux-2.13-0.56.0.2.el5` (2认同)

Luc*_*mon 31

博士回答的帮助下,我写了一个解决方法,将转换放入.bashrc中.如果您没有任何时间戳或已经正确的时间戳,它不会破坏任何内容.

dmesg_with_human_timestamps () {
    $(type -P dmesg) "$@" | perl -w -e 'use strict;
        my ($uptime) = do { local @ARGV="/proc/uptime";<>}; ($uptime) = ($uptime =~ /^(\d+)\./);
        foreach my $line (<>) {
            printf( ($line=~/^\[\s*(\d+)\.\d+\](.+)/) ? ( "[%s]%s\n", scalar localtime(time - $uptime + $1), $2 ) : $line )
        }'
}
alias dmesg=dmesg_with_human_timestamps
Run Code Online (Sandbox Code Playgroud)

此外,还可以很好地读取dmesg时间戳转换逻辑以及如何在没有时间戳的情况下启用时间戳:https: //supportcenter.checkpoint.com/supportcenter/portal?eventSubmit_doGoviewsolutiondetails =&scolutionid = sk92677


小智 16

对于没有"dmesg -T"的系统,例如RHEL/CentOS 6,我喜欢早先由lucas-cimon提供的"dmesg_with_human_timestamps"功能.虽然我们的一些盒子有很长的正常运行时间,但它有点麻烦.事实证明,dmesg中的内核时间戳是从各个CPU保持的正常运行时间值得出的.随着时间的推移,这与实时时钟不同步.因此,最近dmesg条目的最准确转换将基于CPU时钟而不是/ proc /正常运行时间.例如,在这里的特定CentOS 6.6盒子上:

# grep "\.clock" /proc/sched_debug  | head -1
  .clock                         : 32103895072.444568
# uptime
 15:54:05 up 371 days, 19:09,  4 users,  load average: 3.41, 3.62, 3.57
# cat /proc/uptime
32123362.57 638648955.00
Run Code Online (Sandbox Code Playgroud)

考虑到CPU的正常运行时间以毫秒为单位,这里的偏移量接近5个半小时.所以我修改了脚本并在此过程中将其转换为本机bash:

dmesg_with_human_timestamps () {
    FORMAT="%a %b %d %H:%M:%S %Y"

    now=$(date +%s)
    cputime_line=$(grep -m1 "\.clock" /proc/sched_debug)

    if [[ $cputime_line =~ [^0-9]*([0-9]*).* ]]; then
        cputime=$((BASH_REMATCH[1] / 1000))
    fi

    dmesg | while IFS= read -r line; do
        if [[ $line =~ ^\[\ *([0-9]+)\.[0-9]+\]\ (.*) ]]; then
            stamp=$((now-cputime+BASH_REMATCH[1]))
            echo "[$(date +"${FORMAT}" --date=@${stamp})] ${BASH_REMATCH[2]}"
        else
            echo "$line"
        fi
    done
}

alias dmesgt=dmesg_with_human_timestamps
Run Code Online (Sandbox Code Playgroud)


run*_*uhl 12

所以KevZero要求一个不那么神奇的解决方案,所以我想出了以下内容:

sed -r 's#^\[([0-9]+\.[0-9]+)\](.*)#echo -n "[";echo -n $(date --date="@$(echo "$(grep btime /proc/stat|cut -d " " -f 2)+\1" | bc)" +"%c");echo -n "]";echo -n "\2"#e'
Run Code Online (Sandbox Code Playgroud)

这是一个例子:

$ dmesg|tail | sed -r 's#^\[([0-9]+\.[0-9]+)\](.*)#echo -n "[";echo -n $(date --date="@$(echo "$(grep btime /proc/stat|cut -d " " -f 2)+\1" | bc)" +"%c");echo -n "]";echo -n "\2"#e'
[2015-12-09T04:29:20 COT] cfg80211:   (57240000 KHz - 63720000 KHz @ 2160000 KHz), (N/A, 0 mBm), (N/A)
[2015-12-09T04:29:23 COT] wlp3s0: authenticate with dc:9f:db:92:d3:07
[2015-12-09T04:29:23 COT] wlp3s0: send auth to dc:9f:db:92:d3:07 (try 1/3)
[2015-12-09T04:29:23 COT] wlp3s0: authenticated
[2015-12-09T04:29:23 COT] wlp3s0: associate with dc:9f:db:92:d3:07 (try 1/3)
[2015-12-09T04:29:23 COT] wlp3s0: RX AssocResp from dc:9f:db:92:d3:07 (capab=0x431 status=0 aid=6)
[2015-12-09T04:29:23 COT] wlp3s0: associated
[2015-12-09T04:29:56 COT] thinkpad_acpi: EC reports that Thermal Table has changed
[2015-12-09T04:29:59 COT] i915 0000:00:02.0: BAR 6: [??? 0x00000000 flags 0x2] has bogus alignment
[2015-12-09T05:00:52 COT] thinkpad_acpi: EC reports that Thermal Table has changed
Run Code Online (Sandbox Code Playgroud)

如果您希望它执行得更好,请将proc的时间戳放入变量:)


小智 12

dmesg -T可能会显示错误的时间,与date命令输出不同。

解决方法是使用journalctl 和-k, --dmesg。我使用 -k 因为它更短:

journalctl -k
Run Code Online (Sandbox Code Playgroud)

它只会显示内核消息和正确时间。

仅显示匹配短语的内核行:

journalctl -kg phrase
Run Code Online (Sandbox Code Playgroud)


Ann*_*sum 6

如果您没有例如在 Andoid 上的-T选项,您可以使用该版本。以下还解决了其他一些问题:dmesgbusybox

  1. [0.0000]格式前面有一些看起来像是放错位置的颜色信息的东西,例如<6>.
  2. 从浮点数生成整数。

它的灵感来自这篇博文

#!/bin/sh                                                                                                               
# Translate dmesg timestamps to human readable format                                                                   

# uptime in seconds                                                                                                     
uptime=$(cut -d " " -f 1 /proc/uptime)                                                                                  

# remove fraction                                                                                                       
uptime=$(echo $uptime | cut -d "." -f1)                                                                                 

# run only if timestamps are enabled                                                                                    
if [ "Y" = "$(cat /sys/module/printk/parameters/time)" ]; then                                                          
  dmesg | sed "s/[^\[]*\[/\[/" | sed "s/^\[[ ]*\?\([0-9.]*\)\] \(.*\)/\\1 \\2/" | while read timestamp message; do      
    timestamp=$(echo $timestamp | cut -d "." -f1)                                                                       
    ts1=$(( $(busybox date +%s) - $uptime + $timestamp ))                                                               
    ts2=$(busybox date -d "@${ts1}")                                                                                    
    printf "[%s] %s\n" "$ts2" "$message"                                                                                
  done                                                                                                                  
else                                                                                                                    
  echo "Timestamps are disabled (/sys/module/printk/parameters/time)"                                                   
fi                                                                                                                      
Run Code Online (Sandbox Code Playgroud)

但请注意,此实现速度相当慢。


Ste*_*eil 5

在最新版本的dmesg中,您可以致电dmesg -T

  • RC 早在您两年前就已经给出了相同的答案。 (3认同)