私はdmesgタイムスタンプを理解しようとしていますが、それをJava日付/カスタム日付形式に変更するために変換するのは難しいと思っています。
どんな助けも大歓迎です。
サンプルdmesgログ:
[14614.647880] airo(eth1): link lost (missed beacons)
ありがとう!
dmesg
タイムスタンプの理解は非常に簡単です。カーネルが起動してからの秒数です。したがって、起動時間(uptime
)があれば、秒数を加算して、好きな形式で表示できます。
または、-T
オプションを使用して、人間が読める形式を解析することもできます。
manページ から:
-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 answerの助けを借りて、.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
RHEL/CentOS 6などの「dmesg -T」のないシステムの場合、以前に lucas-cimon で提供されていた「dmesg_with_human_timestamps」関数が好きでした。ただし、稼働時間が長い私たちのボックスの一部には少し問題があります。 dmesgのカーネルタイムスタンプは、個々のCPUが保持する稼働時間の値から派生していることがわかります。時間が経つにつれて、これはリアルタイムクロックと同期しなくなります。その結果、最近のdmesgエントリの最も正確な変換は、/ proc/uptimeではなくCPUクロックに基づきます。たとえば、特定の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 はそれほどクラディな解決策を要求しなかったので、次のように思いつきました。
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で指定された経過秒数を加算して、各イベントのタイムスタンプを計算できます。
Andoidの場合のようにdmesg
の-T
オプションがない場合は、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\n" "$ts2" "$message"
done
else
echo "Timestamps are disabled (/sys/module/printk/parameters/time)"
fi
ただし、この実装は非常に遅いことに注意してください。
古いLinuxディストリビューションでは、ラッピングスクリプトを使用することもできます。 PerlまたはPythonで。
こちらのソリューションをご覧ください。
http://linuxaria.com/article/how-to-make-dmesg-timestamp-human-readable?lang=enhttp://jmorano.moretrix.com/2012/ 03/dmesg-human-readable-timestamps /