Respostas:
Entender o dmesg
timestamp é muito simples: é o tempo em segundos desde que o kernel foi iniciado. Então, tendo tempo de inicialização (uptime
), você pode somar os segundos e mostrá-los no formato que desejar.
Ou melhor, você pode usar a -T
opção de linha de comando dmesg
e analisar o formato legível por humanos.
Na página de manual :
-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
, de acordo com as Notas de Lançamento: ftp.kernel.org/pub/linux/utils/util-linux/v2.20/…
Com a ajuda de dr answer, escrevi uma solução alternativa que faz a conversão para colocar em seu .bashrc. Não vai quebrar nada se você não tiver nenhum carimbo de data / hora ou já estiver correto.
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
Além disso, uma boa leitura sobre a lógica de conversão de carimbo de data / hora dmesg e como habilitar carimbos de data / hora quando não houver nenhum: https://supportcenter.checkpoint.com/supportcenter/portal?eventSubmit_doGoviewsolutiondetails=&solutionid=sk92677
local dmesg_bin=$(type -a dmesg | awk 'END { print $NF }')
type
over which
, consulte esta pergunta . Eu editei minha resposta para evitar o tubo triplo inútil.
Para sistemas sem "dmesg -T", como RHEL / CentOS 6, gostei da função "dmesg_with_human_timestamps" fornecida por lucas-cimon anteriormente. Ele tem alguns problemas com algumas de nossas caixas com grande tempo de atividade. Acontece que os timestamps do kernel em dmesg são derivados de um valor de tempo de atividade mantido por CPUs individuais. Com o tempo, isso fica fora de sincronia com o relógio em tempo real. Como resultado, a conversão mais precisa para entradas dmesg recentes será baseada no clock da CPU em vez de / proc / uptime. Por exemplo, em uma caixa CentOS 6.6 particular aqui:
# 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 o tempo de atividade da CPU em milissegundos, há um deslocamento de quase 5 horas e meia aqui. Então, revisei o script e o converti em bash nativo no 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
Então, KevZero solicitou uma solução menos confusa, então eu vim com o seguinte:
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'
Aqui está um exemplo:
$ 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 você quiser que ele tenha um desempenho um pouco melhor, coloque o carimbo de data / hora de proc em uma variável ao invés :)
Nas versões recentes do dmesg, você pode simplesmente ligar dmesg -T
.
Se você não tem a -T
opção de dmesg
como por exemplo no Andoid, você pode usar a busybox
versão. O seguinte resolve também alguns outros problemas:
[0.0000]
formato é precedido por algo que parece informações de cores perdidas, prefixos como<6>
.É inspirado nesta postagem do 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
Observe, no entanto, que essa implementação é bastante lenta.
você precisará fazer referência ao "btime" em / proc / stat, que é o tempo de época do Unix em que o sistema foi inicializado pela última vez. Em seguida, você pode basear-se no tempo de inicialização do sistema e adicionar os segundos decorridos fornecidos em dmesg para calcular a data e hora de cada evento.
Com distros Linux mais antigas, outra opção é usar o script de empacotamento, por exemplo, em Perl ou Python.
Veja as soluções aqui:
http://linuxaria.com/article/how-to-make-dmesg-timestamp-human-readable?lang=en http://jmorano.moretrix.com/2012/03/dmesg-human-readable-timestamps/