Risposte:
Capire il dmesg
timestamp è piuttosto semplice: è il tempo in secondi da quando il kernel è stato avviato. Quindi, avendo il tempo di avvio ( uptime
), puoi sommare i secondi e mostrarli nel formato che preferisci.
O meglio, potresti usare l' -T
opzione della riga di comando dmesg
e analizzare il formato leggibile dall'uomo.
Dalla pagina man :
-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.
rpm -qf /bin/dmesg => util-linux-2.13-0.56.0.2.el5
util-linux 2.20
, secondo le note di rilascio: ftp.kernel.org/pub/linux/utils/util-linux/v2.20/…
Con l'aiuto di dr answer, ho scritto una soluzione alternativa che rende la conversione da inserire nel tuo .bashrc. Non interromperà nulla se non hai alcun timestamp o timestamp già corretti.
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
Inoltre, una buona lettura sulla logica di conversione del timestamp dmesg e su come abilitare i timestamp quando non ce ne sono: https://supportcenter.checkpoint.com/supportcenter/portal?eventSubmit_doGoviewsolutiondetails=&solutionid=sk92677
local dmesg_bin=$(type -a dmesg | awk 'END { print $NF }')
type
over which
, vedere questa domanda . Ho modificato la mia risposta per evitare l'inutile triplo tubo.
Per i sistemi senza "dmesg -T" come RHEL / CentOS 6, mi è piaciuta la funzione "dmesg_with_human_timestamps" fornita da lucas-cimon in precedenza. Tuttavia, ha un po 'di problemi con alcune delle nostre scatole con tempi di attività elevati. Risulta che i timestamp del kernel in dmesg derivano da un valore di uptime mantenuto dalle singole CPU. Nel tempo questo perde la sincronizzazione con l'orologio in tempo reale. Di conseguenza, la conversione più accurata per le voci dmesg recenti sarà basata sull'orologio della CPU anziché su / proc / uptime. Ad esempio, su una particolare scatola CentOS 6.6 qui:
# 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
Considerando il tempo di attività della CPU in millisecondi, qui c'è un offset di quasi 5 ore e mezza. Quindi ho rivisto lo script e l'ho convertito in bash nativo nel processo:
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
Quindi KevZero ha richiesto una soluzione meno complicata, quindi ho pensato a quanto segue:
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'
Ecco un esempio:
$ 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
Se vuoi che funzioni un po 'meglio, metti invece il timestamp da proc in una variabile :)
Nelle versioni recenti di dmesg, puoi semplicemente chiamare dmesg -T
.
Se non hai l' -T
opzione per dmesg
come ad esempio su Andoid, puoi utilizzare la busybox
versione. Quanto segue risolve anche alcuni altri problemi:
[0.0000]
formato è preceduto da qualcosa che assomiglia a informazioni di colore fuori posto, come prefissi <6>
.È ispirato a questo post del 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
Notare, tuttavia, che questa implementazione è piuttosto lenta.
sarà necessario fare riferimento a "btime" in / proc / stat, che è l'ora di Unix in cui il sistema è stato avviato per l'ultima volta. Quindi puoi basarti su quel tempo di avvio del sistema e quindi aggiungere i secondi trascorsi forniti in dmesg per calcolare il timestamp per ogni evento.
Con le vecchie distribuzioni Linux ancora un'altra opzione è usare lo script di wrapping, ad esempio in Perl o Python.
Vedi le soluzioni qui:
http://linuxaria.com/article/how-to-make-dmesg-timestamp-human-readable?lang=en http://jmorano.moretrix.com/2012/03/dmesg-human-readable-timestamps/