it-swarm.com.de

Konvertiert den Zeitstempel von dmesg in ein benutzerdefiniertes Datumsformat

Ich versuche, den dmesg-Zeitstempel zu verstehen, und finde es schwierig, ihn in das Format Java date/custom date) zu konvertieren.

jede Hilfe wird sehr geschätzt.

Beispiel-Dmesg-Protokoll:

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

Vielen Dank!

98
ukanth

Das Verstehen von dmesg Timestamp ist ziemlich einfach: Es ist Zeit in Sekunden, seit der Kernel gestartet wurde. Wenn Sie also die Startzeit (uptime) haben, können Sie die Sekunden addieren und in einem beliebigen Format anzeigen.

Oder besser, Sie könnten die -T Option und analysieren Sie das lesbare Format.

Aus der Manpage :

-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.
154
user180100

Mit Hilfe von dr answer habe ich eine Problemumgehung geschrieben, mit der die Konvertierung in Ihre .bashrc-Datei durchgeführt wird. Es wird nichts kaputt machen, wenn Sie keinen oder bereits korrekte Zeitstempel haben.

dmesg_with_human_timestamps () {
    $(type -P dmesg) "[email protected]" | 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

Lesen Sie auch die dmesg-Zeitstempel-Konvertierungslogik und wie Sie Zeitstempel aktivieren, wenn keine vorhanden sind: https://supportcenter.checkpoint.com/supportcenter/portal?eventSubmit_doGoviewsolutiondetails=&solutionid=sk92677

30
Lucas Cimon

Bei Systemen ohne "dmesg -T" wie RHEL/CentOS 6 hat mir die Funktion "dmesg_with_human_timestamps" von lucas-cimon früher gefallen. Es gibt jedoch einige Probleme mit einigen unserer Boxen, die über eine lange Betriebszeit verfügen. Es stellt sich heraus, dass die Kernel-Zeitstempel in dmesg von einem Betriebszeitwert abgeleitet werden, der von den einzelnen CPUs eingehalten wird. Im Laufe der Zeit wird dies nicht mehr mit der Echtzeituhr synchronisiert. Infolgedessen basiert die genaueste Konvertierung für aktuelle dmesg-Einträge auf der CPU-Uhr und nicht auf/proc/uptime. Zum Beispiel auf einer bestimmten CentOS 6.6-Box hier:

# 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

Berücksichtigt man die CPU-Betriebszeit in Millisekunden, ergibt sich hier ein Versatz von fast 5 1/2 Stunden. Deshalb habe ich das Skript überarbeitet und es dabei in native Bash konvertiert:

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}" [email protected]${stamp})] ${BASH_REMATCH[2]}"
        else
            echo "$line"
        fi
    done
}

alias dmesgt=dmesg_with_human_timestamps
15
Allen Belletti

Also KevZero bat um eine weniger kludige Lösung, also kam ich auf folgendes:

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'

Hier ist ein Beispiel:

$ 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

Wenn Sie möchten, dass es ein bisschen besser läuft, setzen Sie stattdessen den Zeitstempel von proc in eine Variable :)

12
runejuhl

In neueren Versionen von dmesg können Sie einfach dmesg -T Aufrufen.

5
Steffen Heil

sie müssen auf die "btime" in/proc/stat verweisen. Dies ist die Zeit der Unix-Epoche, zu der das System zuletzt gestartet wurde. Dann könnten Sie auf dieser Systemstartzeit aufbauen und dann die in dmesg angegebenen verstrichenen Sekunden addieren, um den Zeitstempel für jedes Ereignis zu berechnen.

3
imcom

Wenn Sie nicht die Option -T Für dmesg haben, wie zum Beispiel für Andoid, können Sie die Version busybox verwenden. Das Folgende löst auch einige andere Probleme:

  1. Dem Format [0.0000] Wird etwas vorangestellt, das wie verlegte Farbinformationen aussieht, Präfixe wie <6>.
  2. Machen Sie ganze Zahlen aus Floats.

Es ist inspiriert von diesem Blog-Beitrag .

#!/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                                                                                                                      

Beachten Sie jedoch, dass diese Implementierung sehr langsam ist.

3
Anne van Rossum

Bei älteren Linux-Distributionen besteht eine weitere Möglichkeit darin, ein Wrapping-Skript zu verwenden, z. in Perl oder Python.

Lösungen finden Sie hier:

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

3