63

I have (for example) this log entry in dmesg output:

[600711.395348] do_trap: 6 callbacks suppressed

Is there a possibility to convert this 'dmesg' time to 'real' time to know, when this event happend?

Jan Marek
  • 2,200

7 Answers7

89

It looks as if it was implemented recently for Quantal (12.10) : see http://brainstorm.ubuntu.com/idea/17829/ .

Basically, dmesg is reported to have a new switch -T, --ctime.


Edit. As another extension on Ignacio's answer, here are some scripts to enhance dmesg output on older systems.

( Note: for the python version of the code shown there, one will want to replace &lt; and &gt; back to <> to make it usable again. )


Finally, for a single value like 600711.395348 one could do

ut=`cut -d' ' -f1 </proc/uptime` 
ts=`date +%s` 
date -d"70-1-1 + $ts sec - $ut sec + $(date +%:::z) hour + 600711.395348 sec" +"%F %T"

and get the event date and time in the local time zone.

( Please note that due to round-off errors the last second digit probably won't be accurate. ) .

Edit(2): Please note that -- as per Womble's comment below, -- this will only work if the machine was not hibernated etc. ( In that case, one shall better look at syslog configs at /etc/*syslog* and check the appropriate files. See also: dmesg vs /var/messages . )

ジョージ
  • 1,028
  • 8
  • 8
  • 6
    And, as an added bonus, if the machine's ever been suspended, you're completely doomed, because the time spent asleep isn't accounted for. – womble Sep 02 '15 at 23:28
  • 1
    Womble's comment is super imporant! It will show the wrong time if using a laptop that hibernates or is set in standby. You should use the /var/log/kern.log file to see the actual file. – oligofren Jan 08 '18 at 09:28
  • One-liner: date -d"1970-01-01 + $(date +%s) sec - $(cut -d' ' -f1 </proc/uptime) sec + 600711.395348 sec" +"%F %T.%N %Z" – kgibm Nov 13 '18 at 20:34
  • Note: I can no longer edit my comment, but instead of %Z, it should be UTC, since date +%s returns seconds since UTC. It would then have to be converted to the local time zone. – kgibm Nov 13 '18 at 20:41
  • 1
    @kgibm : I agree with (2) ; as for (1), it is not that I have anything against one-liners -- but I don't actually see a point for it here: code above is intentionally split in three lines for readability ( I need people to understand how it works, not make it as compact as possible ; for that, I shall better build it up sequentially ) and size ( I would love to have longer variable names, but that makes line 3 look nightmare-ish ); on the other hand, you probably won't type in the whole long line in a terminal, but rather put it in a file and make executable -- so no big win here either. – ジョージ Nov 14 '18 at 05:42
  • @ジョージ I agree with you - your answer teaches better. I was just putting the command in instructions to a customer and thought some people might like a more compact form, but it's definitely for the more advanced users. – kgibm Nov 14 '18 at 05:53
  • @kgibm : I agree as well - I can perfectly understand why one may want to use this form in an e-mail. – ジョージ Nov 14 '18 at 09:21
  • 1
    To add to @womble and oligofren great comments, a good practice can be running "journalctl -k" to see the correct time. For ones who are willing to match a specific phrase, "journalctl -k phrase" can be used. (replace "phrase" with the phrase you're searching for) Credit to 16851556 who answer this here: How do I convert dmesg timestamp to custom date format? – Oz Edri Feb 08 '24 at 09:40
20

To extend on Ignacio's answer, the entries contained in dmesg are typically also logged elsewhere on the system, via syslog, which will give you a "real" timestamp. Unless Ubuntu have changed the Debian-set default, the log entries should be in /var/log/kern.log.

womble
  • 97,049
11

The time given in dmesg is in seconds since kernel startup. So, just add that many seconds to when the kernel started running (hint: uptime).

  • 1
    That will only work if you are using a system that never goes into standby. Otherwise you need to use the logs. – oligofren Jan 08 '18 at 09:29
6

I know this is now old but dmesg now has a built in -e or --reatime option to display the time in the local time.

root@bbs:/var/log# dmesg|tail -1
[50755952.379177] Out of memory in UB 1593: OOM killed process 3183 (sbbs) score 0 vm:747204kB, rss:242764kB, swap:88224kB

root@bbs:/var/log# dmesg -e|tail -1
[Feb20 17:10] Out of memory in UB 1593: OOM killed process 3183 (sbbs) score 0 vm:747204kB, rss:242764kB, swap:88224kB
nelgin
  • 89
  • 2
    This does not work on Ubuntu 18.04. Not sure about others. However dmesg -T does work. See this post https://stackoverflow.com/questions/13890789/how-do-i-convert-dmesg-timestamp-to-custom-date-format – Dave Aug 23 '22 at 17:42
2

On busybox, the 3 liner above didn't work, so here is my way to calculate it one off (replace 1628880.0 with your dmesg timestamp):

perl -e '@a=split(`/proc/uptime`);print scalar(localtime(time()+$a[0] - 1628880.0)."\n");'
2

dmesg | perl -pe 'use Unix::Uptime; s/^\[(.*)\]/localtime(time()-Unix::Uptime->uptime()+$1)/e'

Stone
  • 7,081
  • 1
  • 22
  • 33
0

Also in need of this for MacOS.

Ventura's dmesg has only 2 parameters :

dmesg [-M core] [-N system]

TheUnF
  • 1