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

我想了解dmesg的时间戳,发现很难将其转换为javadate/自定义date格式。

任何帮助深表感谢。

示例dmesg日志:

[14614.647880] airo(eth1): link lost (missed beacons) 

谢谢!

理解dmesg时间戳非常简单:从内核启动到现在是几秒钟的时间。 所以,有了启动uptimeuptime ),你可以加上秒数,并以任何你喜欢的格式显示出来。

或者更好的是,您可以使用-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. 

在博士的帮助下,我写了一个解决方法,将转换放在你的.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 

另外,关于dmesg时间戳转换逻辑以及如何在没有时间戳时启用时间戳: https : //supportcenter.checkpoint.com/supportcenter/portal?eventSubmit_doGoviewsolutiondetails=&solutionid=sk92677

对于没有“dmesg -T”的系统,例如RHEL / CentOS 6,我喜欢早先由lucas-cimon提供的“dmesg_with_human_timestamps”函数。 虽然我们的一些盒子正常运行时间很长,但还是有点麻烦。 发现dmesg中的内核时间戳是从单个CPU保存的正常运行时间值得出的。 随着时间的推移,这与实时时钟不同步。 因此,最近dmesg条目最准确的转换将基于CPU时钟而不是/ proc / uptime。 例如,在一个特定的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 

考虑到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 

所以KevZero请求了一个较less的解决scheme,所以我想出了以下几点:

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

这是一个例子:

 $ 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 

如果你希望它执行得更好一点,把proc的时间戳记放入一个variables中:)

您将需要引用/ proc / stat中的“btime”,这是系统最新启动时的Unix纪元时间。 然后,您可以基于系统启动时间,然后添加在dmesg中给出的已用秒数来计算每个事件的时间戳。

在最近的dmesg版本中,你可以调用dmesg -T

对于较老的Linux发行版,另一个select是使用包装脚本,例如在Perl或Python中。

在这里看到解

http://linuxaria.com/article/how-to-make-dmesg-timestamp-human-readable?lang=en http://jmorano.moretrix.com/2012/03/dmesg-human-readable-timestamps/

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

  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 

但是请注意,这个实现非常慢。