Конвертировать dmesg timestamp в пользовательский формат даты
Я пытаюсь понять временную метку dmesg и найти ее трудно преобразовать, чтобы изменить ее на java date/custom date format.
любая помощь очень ценится.
пример журнала dmesg:
[14614.647880] airo(eth1): link lost (missed beacons)
спасибо!
8 ответов:
понимание
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\n", scalar localtime(time - $uptime + ), ) : $line ) }' } alias dmesg=dmesg_with_human_timestamps
кроме того, хорошее чтение логики преобразования меток времени dmesg и как включить метки времени, когда их нет: https://supportcenter.checkpoint.com/supportcenter/portal?eventSubmit_doGoviewsolutiondetails=&solutionid=sk92677
для систем без "dmesg-T", таких как RHEL/CentOS 6, мне понравилась функция "dmesg_with_human_timestamps", предоставленная Лукас-Кимон раньше. Однако у него есть немного проблем с некоторыми из наших коробок с большим временем безотказной работы. Оказывается, что метки времени ядра в dmesg получены из значения времени безотказной работы, хранящегося отдельными процессорами. Со временем это выходит из синхронизации с часами реального времени. Как результат, наиболее точный перевод на свежие записи команды dmesg будет основываться на тактовой частоте процессора а не /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
учитывая время безотказной работы процессора в миллисекундах, здесь есть смещение почти 5 1/2 часов. Поэтому я пересмотрел скрипт и преобразовал его в native 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 date --date="@$(echo "$(grep btime /proc/stat|cut -d " " -f 2)+" | bc)" +"%c");echo -n "]";echo -n ""#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)+" | bc)" +"%c");echo -n "]";echo -n ""#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 в переменную вместо этого:)
вам нужно будет ссылаться на "btime" в /proc/stat, который является временем эпохи Unix, когда система была загружена последней. Затем вы можете основываться на этом времени загрузки системы, а затем добавить истекшие секунды, указанные в dmesg, чтобы вычислить метку времени для каждого события.
с более старыми дистрибутивами Linux еще один вариант-использовать сценарий обертывания, например, в 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
как например на Andoid, вы можете использоватьbusybox
версия. Следующее решает также некоторые другие вопросы:
- The
[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
обратите внимание, однако, что эта реализация это довольно медленно.