dmesg time to real time

Наверное все видели как выглядят логи в кольцевом буфере ядра. Каждое событие в этом логе имеет timestamp в секундах. Timestump каждого события говорит нам на какой секунде работы системы произошло событие. На самом деле там кроме секунд указываются еще и наносекунды(после точки).

Типичный для меня случай. kdump обработал kernel panic, сдампил содержимое кольцевого буфера(по сути самые актуальные логи перед паникой) и отправил куда то лог и вот он у меня перед глазами. Теперь мне нужно понять в какое время происходили те или иные события а в логе тупа секунды с момента загрузки ядра и это не очень удобно.

Пример событий из лога:

[2003294.556033] [sched_delayed] sched: RT throttling activated
...
[2041172.189030] Kernel panic - not syncing: Watchdog detected hard LOCKUP on cpu 11
...

Что бы перевести время этих событий в реальное время нужно знать время той самой загрузки системы которая закончилась паникой.

Идем на упавший сервер(он уже перезагрузился) и смотрим лог загрузок:

last | grep reboot

reboot   system boot  3.10.0-327.59.1. Sat Apr  7 09:24 - 17:42  (08:18)
reboot   system boot  3.10.0-327.59.1. Wed Mar 14 18:06 - 17:42 (23+23:36)
...

Тут нужно знать с момента какой загрузки у нас лог. В моем случае верхняя строчка это текущая загрузка а лог у меня от пред идущей.

Конвертируем время загрузки в unix time:

date -d "2018-03-14 18:06:00 MSK" +%s
152103996

Прибавляем к нему время события из dmesg: 1521039960 + 2041172 = 1523081132

Переводим в реальное время:

date -d @1523081132
Sat Apr  7 09:05:32 MSK 2018

Это можно автоматизировать с помощью простого скрипта:

#!/bin/bash

# HELP:
#
# dmesg-time-to-human.sh {boot time before crash} {dmesg time to convert}
#
# {boot time before crash} - see `last | grep reboot`
#
# Example:
#
# dmesg-time-converter.sh '2018-03-14 18:06:00 MSK' 2041172
# Sat Apr 7 09:05:32 MSK 2018

BOOT_TIME=$1        # last | grep reboot
DMESG_TIME=$2       # timestump from dmesg

LAST_BOOT_UNIX_TIME=$(date -d "$BOOT_TIME" +%s)
echo $(date -d @$(bc<<<$LAST_BOOT_UNIX_TIME+$DMESG_TIME))

Пример:

dmesg-time-converter.sh '2018-03-14 18:06:00 MSK' 2041172
Sat Apr 7 09:05:32 MSK 2018