Corrélation des horodatages / var / log / *

20

/var/log/messages,, /var/log/sysloget certains autres fichiers journaux utilisent un horodatage qui contient une heure absolue, comme Jan 13 14:13:10.

/var/log/Xorg.0.loget /var/log/dmesg, ainsi que la sortie de $ dmesg, utilisez un format qui ressemble à

[50595.991610] malkovich: malkovich malkovich malkovich malkovich

Je suppose / collecte que les chiffres représentent les secondes et les microsecondes depuis le démarrage.

Cependant, ma tentative de corrélation de ces deux ensembles d'horodatages (en utilisant la sortie de uptime) a donné un écart d'environ 5000 secondes.

C'est à peu près la durée pendant laquelle mon ordinateur a été suspendu.

Existe-t-il un moyen pratique de mapper les horodatages numériques utilisés par dmesg et Xorg en horodatages absolus?

mise à jour

En tant qu'étape préliminaire pour comprendre cela, et aussi pour, espérons-le, clarifier un peu ma question, j'ai écrit un script Python pour analyser /var/log/sysloget produire le décalage temporel. Sur ma machine, exécutant ubuntu 10.10, ce fichier contient de nombreuses lignes d'origine du noyau qui sont estampillées à la fois avec l'horodatage dmesg et l'horodatage syslog. Le script génère une ligne pour chaque ligne de ce fichier qui contient un horodatage du noyau.

Usage:

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

Sortie expurgée (voir ci-dessous pour les définitions des colonnes):

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

... rel_offsetvaut 0 pour toutes les lignes intermédiaires ...

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_offsetest -5280 pour toutes les lignes restantes ...

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

... Les lignes finales sont un peu plus bas, toujours bien au-dessus de la fin de la sortie. Certains d 'entre eux ont probablement été écrits dans dmesgle tampon circulaire d' avant la suspension, et n'ont été propagés syslogqu'après. Cela explique pourquoi tous ont le même horodatage Syslog.

Définitions des colonnes:

abs est le temps enregistré par syslog.

abs_since_bootest la même durée en secondes depuis le démarrage du système, en fonction du contenu /proc/uptimeet de la valeur de time.time().

rel_time est l'horodatage du noyau.

rel_offsetest la différence entre abs_since_bootet rel_time. J'arrondis cela à des dizaines de secondes afin d'éviter les erreurs ponctuelles dues aux sysloghorodatages absolus (c'est-à-dire générés) n'ayant qu'une précision de secondes. En fait, ce n'est pas la bonne façon de le faire, car cela entraîne vraiment (je pense ..) juste une plus petite chance d'avoir une erreur off-by-10. Si quelqu'un a une meilleure idée, faites-le moi savoir.

J'ai également quelques questions sur le format de date de syslog; en particulier, je me demande si une année ne s'y est jamais présentée. Je suppose que non, et dans tous les cas, je pourrais probablement m'aider à ces informations dans TFM, mais si quelqu'un le savait, cela serait utile. .. En supposant, bien sûr, que quelqu'un utilise ce script à un moment donné dans le futur, au lieu de simplement casser quelques lignes de code Perl.

Prochain:

Donc, à moins qu'une révélation bienvenue ne me soit donnée par l'un de vous, ma prochaine étape sera d'ajouter une fonction pour obtenir le décalage temporel pour un horodatage du noyau donné. Je devrais pouvoir alimenter le script un ou un ensemble de syslogs, avec un horodatage du noyau, pour obtenir un horodatage absolu. Ensuite, je peux revenir au débogage de mes problèmes Xorg, qui m'échappent pour le moment.

intuition
la source
1
Je pense que cela est considéré comme un bug et doit être signalé. BTW syslog-ng utilise des horodatages sains avec lesquels vous pouvez trier sort, avoir l'année, le fuseau horaire, etc. +1 pour le script python.
stribika
@stribika: serait-ce un problème de noyau ou un problème syslog? Ou les deux? Il semble que syslog doive être averti que le système a été suspendu. Peut-être qu'il pourrait le faire lui-même avec des hooks de suspension et de reprise.
intuition
Il me semble que le noyau est en faute. Les valeurs rel_time ne "sautent" pas l'heure pendant laquelle le système a été suspendu. Je trouve cependant étrange que le biais commence avant que la suspension ne se produise vraiment. Les valeurs sont déjà erronées pour Freezing user space processesce qui est clairement fait avant de dormir.
stribika
2
@stribika: Ma théorie de travail à ce sujet est que ces événements ne sont pas diffusés dans syslog avant la reprise, car ils se produisent après la suspension de syslog lui-même.
intuition
@stribika: De plus, vous avez raison de dire que le noyau est "en faute": si je comprends bien (après reconsidération), syslog préfixe simplement l'horodatage absolu au texte (en commençant par [12345.6789]..) émis par le noyau, donc il fait les choses correctement , sous réserve des problèmes traités par mon dernier commentaire. Je ne suis pas sûr de ce que le noyau devrait vraiment faire ici; cela dépend de ce que ces horodatages relatifs au démarrage sont censés indiquer. Le temps d'exécution (par opposition au temps écoulé depuis le démarrage) peut être significatif dans certains contextes. Je suppose que dans l'idéal, il y aurait un enregistrement fiable de ces deux valeurs.
intuition

Réponses:

4

Problème intéressant, je ne suis pas sûr d'avoir déjà essayé de le faire. Mais j'ai remarqué l'horodatage dont vous parlez et je l'ai toujours cru être quelques secondes depuis le démarrage.

Dans mon syslog que j'ai sur mon serveur, j'ai:

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

J'imagine que c'est assez cohérent parmi la plupart des distributions Linux car c'est le noyau qui crache ses trucs.

Et ici, j'ai la date avec l'horodatage.

Ryan Gibbons
la source
3

Vous pouvez essayer ceci:

Tout d'abord, obtenez l'horodatage du fichier dmesg (mon hypothèse est que ce sera l'heure de dmesg 0). Vous utiliserez

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

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

Vous pouvez convertir les secondes en une date lisible par l'homme avec

perl -e 'print scalar localtime(1294941018)' 

Donc, pour voir une heure d'événement lisible, ajoutez les secondes de l'événement dans dmesg. Si l'événement dmesg a duré 55,290387 secondes, ajoutez 55 ou 55.290387:

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

Une autre façon de transformer les secondes enracinées dans l'époque en heure lisible est d'utiliser la date -d comme suggéré. Si vous dites à «date» de représenter une heure fournie avec -d, vous pouvez indiquer que l'heure à convertir est en secondes depuis l'époque en utilisant @.

date -d "@1294953978"

Cela vous donne quelque chose comme "Thu Jan 13 15:26:18 CST 2011" en sortie.

date +% s
affichera l'heure actuelle au format secondes depuis l'époque.

Je ne me souviens pas comment faire des calculs shell, donc j'utilise généralement la méthode perl comme ci-dessus. :)

belacqua
la source
1
@jgbelacqua: Vous voulez date -d @$((1294953978 + 55)), au moins sous bash. Cependant, certains horodatages du noyau sont asymétriques, ce qui signifie que les heures produites par cette méthode seraient antérieures à leurs horodatages correspondants /var/log/syslog. Il semble que cela se produise à la suite d'événements de suspension sur RAM, probablement en plus de l'hibernation et éventuellement d'autres choses, car le temps du noyau n'augmente pas pendant ces périodes. Voir la mise à jour de la question pour plus d'informations.
intuition
2

Le moyen le plus simple de mapper le nombre de dmesg à une date est d'utiliser le dateprogramme.

date -d "-50595 seconds"

Cette commande affiche la date de l'heure actuelle moins 50595 secondes.

De man date:

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

Le nombre est égal au temps de mise sous tension et non au temps écoulé depuis le démarrage.

Lekensteyn
la source
2

Puisque vous avez noté le décalage temporel lors de la suspension / reprise, je noterai que cela est documenté à au moins un endroit. La page de manuel dmesg (1) indique:

La source de temps utilisée pour les journaux n'est pas mise à jour après la suspension / reprise du système.

Je n'ai pas trouvé de moyen de faire en sorte que le noyau garde ces horodatages synchronisés avec l'heure du mur.

Andrew
la source
1

Rapide, sale, fonctionne.

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

Contenu de ce script:

$ 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 $_;
}

Voici un exemple de sortie:

[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
la source
1
Je suppose que vous n'avez lu que les deux premiers paragraphes de la question. Découvrez-le à nouveau plus en détail. Ou bien, essayez de suspendre votre ordinateur et de vérifier si votre script signale correctement les horodatages absolus des nouveaux messages enregistrés.
intuition