Преобразование dmesg timestamp в пользовательский формат даты

Я пытаюсь понять временную метку dmesg и трудно преобразовать ее, чтобы изменить ее на формат даты/пользовательской даты java.

любая помощь очень ценится.

Пример dmesg log:

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

Спасибо!

+84
15 дек. '12 в 8:55
источник поделиться
8 ответов

Понимание dmesg timestamp довольно просто: это время в секундах с момента запуска ядра. Итак, имея время запуска (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.
+134
15 дек. '12 в 9:01
источник

С помощью ответа 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 + $1), $2 ) : $line )
        }'
}
alias dmesg=dmesg_with_human_timestamps

Кроме того, хорошее прочтение по логике преобразования меток времени dmesg и как включить метки времени, когда их нет: https://supportcenter.checkpoint.com/supportcenter/portal?eventSubmit_doGoviewsolutiondetails=&solutionid=sk92677

+26
09 окт. '13 в 12:39
источник

Для систем без "dmesg -T", таких как RHEL/CentOS 6, мне понравилась функция "dmesg_with_human_timestamps", предоставленная lucas-cimon ранее. У этого есть немного проблем с некоторыми из наших коробок с большим временем безотказной работы, хотя. Оказывается, что метки времени ядра в 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 часов. Поэтому я пересмотрел script и преобразовал его в 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
+12
01 апр. '16 в 16:21
источник

Поэтому 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 в переменную :)

+10
10 дек. '15 в 2:18
источник

В последних версиях dmesg вы можете просто вызвать dmesg -T.

+4
10 июл. '14 в 8:45
источник

вам нужно будет ссылаться на "btime" в /proc/stat, который является временем эпохи Unix, когда система была последней загружена. Затем вы можете основываться на этом времени загрузки системы, а затем добавить в прошедшие секунды, заданные в dmesg, для вычисления отметки времени для каждого события.

+3
05 февр. '13 в 2:41
источник

С более старыми дистрибутивами Linux еще один вариант - использовать упаковку script, например. в 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/

+3
14 авг. '13 в 10:37
источник

Если у вас нет опции -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\n" "$ts2" "$message"                                                                                
  done                                                                                                                  
else                                                                                                                    
  echo "Timestamps are disabled (/sys/module/printk/parameters/time)"                                                   
fi                                                                                                                      

Обратите внимание, однако, что эта реализация выполняется довольно медленно.

+2
13 июн. '15 в 22:05
источник

Посмотрите другие вопросы по меткам или Задайте вопрос