我试图理解dmesg时间戳,并发现很难将其转换为更改为Java日期/自定义日期格式。
任何帮助深表感谢。
示例dmesg日志:
[14614.647880] airo(eth1): link lost (missed beacons)
谢谢!
答案
理解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.
另一答案
在dr回答的帮助下,我写了一个解决方法,将转换放入.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
", scalar localtime(time - $uptime + $1), $2 ) : $line )
}'
}
alias dmesg=dmesg_with_human_timestamps
另一答案
对于没有“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
考虑到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要求一个较少的kludgy解决方案,所以我想出了以下内容:
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'
这是一个例子:
$ 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的时间戳放入变量:)
另一答案
在dmesg的最新版本中,您可以调用dmesg -T。
另一答案
你需要在/ proc / stat中引用“btime”,这是系统最新启动时的Unix纪元时间。然后,您可以基于该系统启动时间,然后添加dmesg中给出的经过的秒数来计算每个事件的时间戳。
另一答案
对于较旧的Linux发行版,另一种选择是使用包装脚本,例如在Perl或Python中。
请在此处查看解
另一答案
如果您没有-T的dmesg选项,例如在Andoid上,您可以使用busybox版本。以下解决了其他一些问题:
[0.0000]格式之前的东西看起来像错误的颜色信息,前缀像<6>。
从浮点数制作整数。
#!/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
" "$ts2" "$message"
done
else
echo "Timestamps are disabled (/sys/module/printk/parameters/time)"
fi
但请注意,此实现非常慢。