Converter a data-limite do dmesg para um formato de data personalizado
estou a tentar compreender o calendário do dmesg e acho difícil convertê-lo para o formato data/data personalizada java.
Qualquer ajuda é muito apreciada.Amostra de registo de dmesg:
[14614.647880] airo(eth1): link lost (missed beacons)
Obrigado!
8 answers
Compreender dmesg
a hora é muito simples: é tempo em segundos desde que o kernel começou. Então, tendo tempo de inicialização (uptime
), você pode adicionar os segundos e mostrá-los no formato que quiser.
Ou melhor, você poderia usar a opção -T
e analisar o formato legível por humanos.
-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.
Com a ajuda da resposta do Dr. , escrevi uma solução que faz a conversão para colocar em ti .bashrc. Ele não vai quebrar nada se você não tiver qualquer timestamp ou já está correto timestamps.
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
Também, uma boa leitura sobre a lógica de conversão de tempo do dmesg e como activar as datas quando não houver nenhuma: https://supportcenter.checkpoint.com/supportcenter/portal?eventSubmit_doGoviewsolutiondetails=&solutionid=sk92677
Para sistemas sem " dmesg-T "como o RHEL/CentOS 6, gostei da função" dmesg_with_human_timestamps " fornecida anteriormente por lucas-cimon. Tem um pouco de problema com algumas das nossas caixas com grande tempo de funcionamento. Acontece que os tempos do kernel em dmesg são derivados de um valor de uptime mantido por CPUs individuais. Com o tempo isto fica fora de sincronia com o relógio em tempo real. Como resultado, a conversão mais precisa para entradas recentes do dmesg será baseada no relógio CPU rather than / proc / uptime. Por exemplo, em uma caixa de 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
Tendo em conta que o tempo de funcionamento da CPU está em milissegundos, há uma compensação de quase 5 horas e meia aqui. Então eu revisei o script e converti - o para 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 o KevZero pediu uma solução menos desleixada, por isso inventei o seguinte:
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'
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 quiser que o desempenho seja um pouco melhor, coloque o timestamp do proc numa variável em vez disso:)
Nas versões recentes do dmesg, basta ligar para {[[0]}.
Você terá de referenciar o "btime" em /proc/stat, que é o tempo da época Unix quando o sistema foi reiniciado. Então você pode basear-se nesse tempo de arranque do sistema e, em seguida, adicionar os segundos decorridos indicados no dmesg para calcular o tempo de amostragem para cada evento.
Com distros Linux mais antigos, outra opção é usar script de embrulho, 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/
Se não tiver a opção -T
Para dmesg
como por exemplo no Andóide, pode usar a versão busybox
. O seguinte resolve também algumas outras questões:
- o formato
[0.0000]
é precedido por algo que se parece com informações de cores erradas, prefixos como<6>
. - Fazer inteiros de carros alegóricos.
É inspirado por Este post no 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
Note-se, no entanto, que esta execução é bastante lenta.