Convertir l’horodatage dmesg au format de date personnalisé

J’essaie de comprendre l’horodatage dmesg et j’ai du mal à le convertir pour le changer en date de java / format de date personnalisé.

Toute aide est très appréciée.

Exemple de journal de dmesg:

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

Merci!

Comprendre l’horodatage de dmesg est assez simple: le kernel a démarré en quelques secondes. Ainsi, avec le temps de démarrage ( uptime ), vous pouvez additionner les secondes et les afficher dans le format de votre choix.

Ou mieux, vous pouvez utiliser l’option -T et parsingr le format lisible par l’homme.

De la page de manuel :

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

Avec l’aide de dr answer, j’ai écrit une solution de contournement qui fait la conversion à mettre dans votre .bashrc. Il ne cassera rien si vous n’avez pas d’horodatage ou d’horodatage correct.

 dmesg_with_human_timestamps () { $(type -P dmesg) "$@" | perl -w -e 'use ssortingct; 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 

En outre, une bonne lecture de la logique de conversion de l’horodatage dmesg et de la manière d’activer les horodatages lorsqu’il n’y en a pas: https://supportcenter.checkpoint.com/supportcenter/portal?eventSubmit_doGoviewsolutiondetails=&solutionid=sk92677

Pour les systèmes sans “dmesg -T” tels que RHEL / CentOS 6, j’ai aimé la fonction “dmesg_with_human_timestamps” fournie par lucas-cimon plus tôt. Il y a un peu de problèmes avec certaines de nos boîtes avec une disponibilité élevée. Il s’avère que les horodatages du kernel dans dmesg sont dérivés d’une valeur de disponibilité conservée par des processeurs individuels. Au fil du temps, cela ne correspond plus à l’horloge temps réel. En conséquence, la conversion la plus précise pour les entrées récentes de dmesg sera basée sur l’horloge du processeur plutôt que sur / proc / uptime. Par exemple, sur un boîtier CentOS 6.6 particulier:

 # 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 

Compte tenu de la disponibilité du processeur en millisecondes, il y a un décalage de près de 5 heures et demie. J’ai donc révisé le script et l’ai converti en bash natif dans le processus:

 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 

Donc, KevZero a demandé une solution moins kludgy, donc je suis venu avec les éléments suivants:

 sed -r 's#^\[([0-9]+\.[0-9]+)\](.*)#echo date --date="@$(echo "$(grep btime /proc/stat|cut -d " " -f 2)+\1" | bc)" +"%c");echo -n "]";echo -n "\2"#e' 

Voici un exemple:

 $ 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 

Si vous voulez qu’il fonctionne un peu mieux, placez l’horodatage de proc dans une variable à la place 🙂

Dans les versions récentes de dmesg, vous pouvez simplement appeler dmesg -T .

vous devrez faire référence au “btime” dans / proc / stat, qui est l’heure de pointe d’Unix au moment du dernier démarrage du système. Ensuite, vous pouvez vous baser sur cette heure de démarrage du système, puis append les secondes écastings dans dmesg pour calculer l’horodatage de chaque événement.

Avec les anciennes dissortingbutions Linux, une autre option consiste à utiliser un script d’encapsulation, par exemple en Perl ou en Python.

Voir les solutions ici:

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

Si vous n’avez pas l’option -T pour dmesg comme par exemple sur Andoid, vous pouvez utiliser la version busybox . Ce qui suit résout également d’autres problèmes:

  1. Le format [0.0000] est précédé de quelque chose qui ressemble à des informations de couleur égarées, des préfixes tels que <6> .
  2. Faire des entiers à partir de flotteurs.

Il est inspiré par ce billet de blog .

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

Notez cependant que cette implémentation est assez lente.