Korrelieren von / var / log / * Zeitstempeln

20

/var/log/messages, /var/log/syslogUnd einige andere Protokolldateien verwenden , um einen Zeitstempel , die eine absolute Zeit enthält, wie Jan 13 14:13:10.

/var/log/Xorg.0.logund /var/log/dmesg, sowie die Ausgabe von $ dmesg, verwenden Sie ein Format, das aussieht

[50595.991610] malkovich: malkovich malkovich malkovich malkovich

Ich vermute, dass die Zahlen Sekunden und Mikrosekunden seit dem Start darstellen.

Mein Versuch, diese beiden Zeitstempelsätze (unter Verwendung der Ausgabe von uptime) zu korrelieren, ergab jedoch eine Diskrepanz von etwa 5000 Sekunden.

Dies ist ungefähr die Zeit, für die mein Computer angehalten wurde.

Gibt es eine bequeme Möglichkeit, die von dmesg und Xorg verwendeten numerischen Zeitstempel in absolute Zeitstempel umzuwandeln?

aktualisieren

Als ersten Schritt, um dies herauszufinden, und um meine Frage hoffentlich etwas klarer zu machen, habe ich ein Python-Skript geschrieben, um den Zeitversatz zu analysieren /var/log/syslogund auszugeben. Auf meinem Computer, auf dem Ubuntu 10.10 ausgeführt wird, enthält diese Datei zahlreiche vom Kernel stammende Zeilen, die sowohl mit dem Zeitstempel dmesg als auch mit dem Zeitstempel syslog versehen sind. Das Skript gibt für jede Zeile in dieser Datei eine Zeile aus, die einen Kernel-Zeitstempel enthält.

Verwendung:

python syslogdriver.py /var/log/syslog | column -nts $'\t'

Freigegebene Ausgabe (siehe unten für Spaltendefinitionen):

abs              abs_since_boot  rel_time      rel_offset  message
Jan 13 07:49:15  32842.1276569   32842.301498  0           malkovich malkovich

... rel_offsetist 0 für alle dazwischenliegenden Zeilen ...

Jan 13 09:55:14  40401.1276569   40401.306386  0           PM: Syncing filesystems ... done.
Jan 13 09:55:14  40401.1276569   40401.347469  0           PM: Preparing system for mem sleep
Jan 13 11:23:21  45688.1276569   40402.128198  -5280       Skipping EDID probe due to cached edid
Jan 13 11:23:21  45688.1276569   40402.729152  -5280       Freezing user space processes ... (elapsed 0.03 seconds) done.
Jan 13 11:23:21  45688.1276569   40402.760110  -5280       Freezing remaining freezable tasks ... (elapsed 0.01 seconds) done.
Jan 13 11:23:21  45688.1276569   40402.776102  -5280       PM: Entering mem sleep

... rel_offsetist -5280 für alle verbleibenden Zeilen ...

Jan 13 11:23:21  45688.1276569   40403.149074  -5280       ACPI: Preparing to enter system sleep state S3
Jan 13 11:23:21  45688.1276569   40403.149477  -5280       PM: Saving platform NVS memory
Jan 13 11:23:21  45688.1276569   40403.149495  -5280       Disabling non-boot CPUs ...
Jan 13 11:23:21  45688.1276569   40403.149495  -5280       Back to C!
Jan 13 11:23:21  45688.1276569   40403.149495  -5280       PM: Restoring platform NVS memory
Jan 13 11:23:21  45688.1276569   40403.151034  -5280       ACPI: Waking up from system sleep state S3

... Die letzten Zeilen kommen etwas weiter unten, immer noch weit über dem Ende der Ausgabe. Einige von ihnen wurden vermutlich dmesgvor dem Suspend in den Ringpuffer geschrieben und erst syslogdanach weitergegeben. Dies erklärt, warum alle den gleichen Syslog-Zeitstempel haben.

Spaltendefinitionen:

abs ist die von syslog protokollierte Zeit.

abs_since_bootist dieselbe Zeit in Sekunden seit dem Systemstart, basierend auf dem Inhalt von /proc/uptimeund dem Wert von time.time().

rel_time ist der Kernel-Zeitstempel.

rel_offsetist der Unterschied zwischen abs_since_bootund rel_time. Ich runde dies auf zehn Sekunden, um einmalige Fehler zu vermeiden, da die absoluten (dh sysloggenerierten) Zeitstempel nur eine Sekundengenauigkeit haben. Das ist eigentlich nicht der richtige Weg, da es (glaube ich) nur zu einer geringeren Wahrscheinlichkeit eines Off-by-10-Fehlers führt. Wenn jemand eine bessere Idee hat, lass es mich wissen.

Ich habe auch einige Fragen zum Datumsformat von Syslog. Insbesondere frage ich mich, ob jemals ein Jahr darin auftaucht. Ich vermute nein, und auf jeden Fall könnte ich mir höchstwahrscheinlich diese Informationen in TFM zu Nutze machen, aber wenn jemand es zufällig weiß, wäre es nützlich. Vorausgesetzt natürlich, dass jemand dieses Skript irgendwann in der Zukunft verwendet, anstatt nur ein paar Zeilen Perl-Code herauszuschleudern.

Nächster:

Wenn mir also keiner von Ihnen eine willkommene Offenbarung gibt, besteht mein nächster Schritt darin, eine Funktion hinzuzufügen, um den Zeitversatz für einen bestimmten Kernel-Zeitstempel zu ermitteln. Ich sollte in der Lage sein, dem Skript einen oder mehrere Syslogs zusammen mit einem Kernel-Zeitstempel zuzuweisen, um einen absoluten Zeitstempel zu erhalten. Dann kann ich wieder meine Xorg-Probleme beheben, die mir im Moment entgehen.

intuitiert
quelle
1
Ich denke, dies ist ein Fehler und sollte gemeldet werden. BTW syslog-ng verwendet vernünftige Zeitstempel, mit denen Sie sortieren können sort, die Jahr, Zeitzone usw. + 1 für das Python-Skript haben.
Stribika
@stribika: Wäre das ein Kernel- oder ein Syslog-Problem? Oder beides? Scheint, als müsste Syslog benachrichtigt werden, dass das System angehalten wurde. Vielleicht könnte es dies selbst tun, indem Hooks angehalten und fortgesetzt werden.
Intuited
Mir scheint, der Kernel ist schuld. Die rel_time-Werte "überspringen" nicht die Zeit, während das System angehalten wurde. Ich finde es jedoch seltsam, dass der Versatz beginnt, bevor die Unterbrechung wirklich passiert. Die Werte sind bereits falsch, Freezing user space processeswas eindeutig vor dem Schlafengehen erfolgt.
Stribika
2
@stribika: Meine Arbeitstheorie dazu lautet, dass diese Ereignisse erst nach dem Resume an Syslog übertragen werden, da sie auftreten, nachdem Syslog selbst angehalten wurde.
Intuited
@stribika: Sie haben auch Recht, wenn es darum geht, dass der Kernel "schuld" ist: So wie ich es verstehe (nach einer erneuten Überlegung), fügt syslog dem vom Kernel ausgegebenen Text (beginnend mit [12345.6789]..) lediglich den absoluten Zeitstempel hinzu , damit die Dinge korrekt ausgeführt werden , vorbehaltlich der in meinem letzten Kommentar behandelten Fragen. Ich bin mir nicht sicher, was der Kernel hier wirklich tun soll. Dies hängt davon ab, was diese startrelativen Zeitstempel anzeigen sollen. Die Laufzeit (im Gegensatz zur Zeit seit dem Start) kann in manchen Zusammenhängen von Bedeutung sein. Idealerweise würde es eine zuverlässige Aufzeichnung dieser beiden Werte geben.
Intuited

Antworten:

4

Interessantes Problem, Ich bin mir nicht sicher, ob ich es jemals versucht habe. Aber ich habe den Zeitstempel bemerkt, von dem Sie sprechen, und ich habe immer geglaubt, dass er Sekunden nach dem Hochfahren ist.

In meinem Syslog, das ich auf meinem Server habe, habe ich:

Jan 10 19:58:55 wdgitial kernel: [    0.000000] Initializing cgroup subsys cpuset
Jan 10 19:58:55 wdgitial kernel: [    0.000000] Initializing cgroup subsys cpu
Jan 10 19:58:55 wdgitial kernel: [    0.000000] Linux version 2.6.32-21-server (buildd@yellow) (gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5) ) #32-Ubuntu SMP Fri Apr 16     09:17:34 UTC 2010 (Ubuntu 2.6.32-21.32-server 2.6.32.11+drm33.2)
Jan 10 19:58:55 wdgitial kernel: [    0.000000] Command line:  root=/dev/xvda1 ro quiet splash

Ich würde mir vorstellen, dass dies bei den meisten Linux-Distributionen ziemlich konsistent ist, da dies der Kernel ist, der das Zeug ausspuckt.

Und hier habe ich das Datum zusammen mit dem Zeitstempel.

Ryan Gibbons
quelle
3

Sie können dies ausprobieren:

Holen Sie sich zuerst den Zeitstempel der dmesg-Datei (ich gehe davon aus, dass dies die Zeit 0 von dmesg ist). Du wirst verwenden

ls -l --time-style = +% s

/var/log$ ls -l --time-style=+%s dmesg
-rw-r----- 1 root adm 56181 1294941018 dmesg

Mit können Sie die Sekunden in ein lesbares Datum umwandeln

perl -e 'print scalar localtime(1294941018)' 

Um eine lesbare Ereigniszeit anzuzeigen, fügen Sie in dmesg die Sekunden des Ereignisses hinzu. Wenn das dmesg-Ereignis 55,290387 Sekunden lang war, fügen Sie 55 oder 55,290387 hinzu:

perl -e 'print scalar localtime(1294953978 + 55)'

Eine andere Möglichkeit, Sekunden mit epochaler Wurzel in lesbare Zeit umzuwandeln, ist die vorgeschlagene Verwendung von Datum -d. Wenn Sie 'date' anweisen, eine mit -d gelieferte Zeit darzustellen, können Sie mit @ angeben, dass die zu konvertierende Zeit in Sekunden seit der Epoche angegeben werden soll.

date -d "@1294953978"

Dies gibt Ihnen so etwas wie "Do Jan 13 15:26:18 CST 2011" als Ausgabe.

Datum +% s
druckt die aktuelle Zeit im Format "Sekunden seit Epoche".

Ich kann mich nicht erinnern, wie man Shell-Mathe macht, deshalb benutze ich normalerweise die Perl-Methode wie oben. :)

belacqua
quelle
1
@jgbelacqua: Du willst es date -d @$((1294953978 + 55))zumindest unter Druck setzen. Einige Kernel-Zeitstempel sind jedoch verzerrt, was bedeutet, dass die durch diese Methode erzeugten Zeiten früher sind als die entsprechenden Zeitstempel in /var/log/syslog. Es sieht so aus, als ob dies auf Ereignisse im Zusammenhang mit dem Suspend-to-RAM zurückzuführen ist, vermutlich zusätzlich zum Ruhezustand und möglicherweise auf andere Ereignisse, da die Kernel-Zeit in diesen Zeiträumen nicht inkrementiert wird. Weitere Informationen finden Sie im Fragen-Update.
Intuited
2

Der einfachste Weg, die Nummer von dmesg auf ein Datum abzubilden, ist die Verwendung des dateProgramms.

date -d "-50595 seconds"

Dieser Befehl zeigt das Datum für die aktuelle Zeit minus 50595 Sekunden an.

Von man date:

-d, --date=STRING
       display time described by STRING, not `now'

Die Zahl entspricht der Einschaltzeit und nicht der seit dem Start verstrichenen Zeit.

Lekensteyn
quelle
2

Da Sie festgestellt haben, dass sich die Zeitverschiebung während der Unterbrechung / Wiederaufnahme geändert hat, wird dies an mindestens einer Stelle dokumentiert. Die Manpage von dmesg (1) sagt:

Die für die Protokolle verwendete Zeitquelle wird nach SUSPEND / RESUME des Systems nicht aktualisiert.

Ich habe keine Möglichkeit gefunden, den Kernel dazu zu bringen, diese Zeitstempel mit der Wandzeit synchron zu halten.

Andrew
quelle
1

Schnell, dreckig, funktioniert.

$ dmesg | grep 3w | perl /root/print_time_offset.pl

Inhalt dieses Skripts:

$ cat /root/print_time_offset.pl

#!/usr/bin/perl

$uptime = `cat /proc/uptime | awk '{print $1}';`;
$boot = time() - $uptime;
chomp $boot;
while (<STDIN>) {
        if ($_ =~ /^\[([\s\d\.]+)\]/) {
                $time_offset = $1;
        }
        $real_time = sprintf scalar localtime($boot + $time_offset);
        $_ =~ s/\[[\s\d\.]+\]/\[$real_time\]/;
        print $_;
}

Die Beispielausgabe lautet wie folgt:

[Mon Feb 21 23:06:33 2011] 3ware 9000 Storage Controller device driver for Linux v2.26.02.012.
[Mon Feb 21 23:06:33 2011] 3w-9xxx 0000:03:00.0: PCI INT A -> GSI 16 (level, low) -> IRQ 16
[Mon Feb 21 23:06:33 2011] 3w-9xxx 0000:03:00.0: setting latency timer to 64
[Mon Feb 21 23:06:33 2011] scsi4 : 3ware 9000 Storage Controller
[Mon Feb 21 23:06:33 2011] 3w-9xxx: scsi4: Found a 3ware 9000 Storage Controller at 0xfbcde000, IRQ: 16.
[Mon Feb 21 23:06:34 2011] 3w-9xxx: scsi4: Firmware FE9X 4.08.00.006, BIOS BE9X 4.08.00.001, Ports: 4.
[Mon Feb 21 23:06:35 2011] 3w-9xxx: scsi4: ERROR: (0x03:0x0101): Invalid command opcode:opcode=0x85.
[Mon Feb 21 23:06:35 2011] 3w-9xxx: scsi4: ERROR: (0x03:0x0101): Invalid command opcode:opcode=0x85.
[Mon Feb 21 23:06:35 2011] 3w-9xxx: scsi4: ERROR: (0x03:0x0101): Invalid command opcode:opcode=0x85.
[Mon Feb 21 23:06:35 2011] 3w-9xxx: scsi4: ERROR: (0x03:0x0101): Invalid command opcode:opcode=0x85.
[Mon Feb 21 23:06:35 2011] 3w-9xxx: scsi4: ERROR: (0x03:0x0101): Invalid command opcode:opcode=0x85.
[Mon Feb 21 23:06:35 2011] 3w-9xxx: scsi4: ERROR: (0x03:0x0101): Invalid command opcode:opcode=0x85.
[Sat Feb 26 02:01:01 2011] 3w-9xxx: scsi4: AEN: INFO (0x04:0x0029): Verify started:unit=0, subunit=1.
[Sat Feb 26 02:01:01 2011] 3w-9xxx: scsi4: AEN: INFO (0x04:0x0029): Verify started:unit=0, subunit=0.
[Sat Feb 26 16:49:13 2011] 3w-9xxx: scsi4: AEN: INFO (0x04:0x002B): Verify completed:unit=0, subunit=1.
[Sat Feb 26 17:07:19 2011] 3w-9xxx: scsi4: AEN: INFO (0x04:0x002B): Verify completed:unit=0, subunit=0.
[Sat Mar  5 02:00:16 2011] 3w-9xxx: scsi4: AEN: INFO (0x04:0x0029): Verify started:unit=0, subunit=1.
[Sat Mar  5 02:00:16 2011] 3w-9xxx: scsi4: AEN: INFO (0x04:0x0029): Verify started:unit=0, subunit=0.
[Sat Mar  5 18:48:57 2011] 3w-9xxx: scsi4: AEN: INFO (0x04:0x002B): Verify completed:unit=0, subunit=1.
[Sat Mar  5 19:05:17 2011] 3w-9xxx: scsi4: AEN: INFO (0x04:0x002B): Verify completed:unit=0, subunit=0.
[Sat Mar 12 02:00:30 2011] 3w-9xxx: scsi4: AEN: INFO (0x04:0x0029): Verify started:unit=0, subunit=1.
[Sat Mar 12 02:00:30 2011] 3w-9xxx: scsi4: AEN: INFO (0x04:0x0029): Verify started:unit=0, subunit=0.
Dacav
quelle
1
Ich vermute, Sie haben nur die ersten paar Absätze der Frage gelesen. Probieren Sie es noch einmal genauer aus. Alternativ können Sie versuchen, Ihren Computer anzuhalten und zu überprüfen, ob Ihr Skript die absoluten Zeitstempel neu protokollierter Nachrichten korrekt ausgibt.
intuited