1

In Fedora 29 (which I'm forced to use), dmesg lacks the options --since and --until like journalctl does.

journalctl --since "2022-12-20 09:00:00" --until "2022-12-20 10:00:00"

How dmesg logs within 9AM to 10AM of Dec 20 can be filtered to be shown?

Damon
  • 13
  • 1
    Did you check the man page of dmesg? https://man7.org/linux/man-pages/man1/dmesg.1.html – Romeo Ninov Dec 21 '22 at 18:15
  • Yes, it lacks the options since and until in the version I have (2.32.1) – Damon Dec 21 '22 at 21:58
  • @Damon do you have --time-format option in your dmesg version? It should be useful to know if you do it to can run this command and parse it correctly: sudo dmesg --time-format 'ctime' – Edgar Magallon Dec 22 '22 at 02:18
  • journalctl is also able to show dmesg messages by using sudo journalctl -k (but given that you say that journalctl does not have the options --since and --until then this is not so useful) – Edgar Magallon Dec 22 '22 at 02:20
  • Actually, my wording was confusing, journalctl has those options under my system. I will check -k tomorrow to see if I get the oom-kill log which is the one I care about. My dmesg also has --time-format as an option. I noticed I can use date -d $(dmesg -T --time-format iso | grep -w "oom-kill" | cut -d ',' -f 1) +%s to get the time of the log (in seconds from epoch) for doing comparison. – Damon Dec 22 '22 at 02:37
  • @Damon then you can use sudo journalctl -k --since "2022-12-20 09:00:00" --until "2022-12-20 10:00:00" without having to parsedmesg. Hope that helps! – Edgar Magallon Dec 22 '22 at 04:23
  • journalctl -k gives me this: -- Logs begin at Tue 2019-01-29 17:48:05 PST, end at Thu 2022-12-22 09:20:36 PST. -- -- No entries -- – Damon Dec 22 '22 at 17:23
  • @Damon Are you running with sudo? I also have that output if I do not use sudo – Edgar Magallon Dec 22 '22 at 22:16
  • @Edgar with or without sudo, it's the same behavior. (I'm logged in as root) – Damon Dec 28 '22 at 01:02
  • @Edgar, actually, your suggestion works! I was using a lxc and running dmesg on the container. dmesg works in there since it shows the identical logs as physical host does. But journalctl doesn't show any logs on the container, only the physical host! Thank you! – Damon Dec 30 '22 at 19:51
  • @Damon that explains why journalctl did not work. It'd be interesting if journalctl can/could show logs from containers such as lxc,docker,podman (maybe journalctl can get logs from containers created by systemd-nspawn). I will search about that :). – Edgar Magallon Dec 30 '22 at 21:58

2 Answers2

1

The --time-format long option for dmesg is a possibility using the iso format:

(note the T and no space between the date and the time, due to the iso format)

The sed only works if you have a line with 2022-12-12T09 and a line with 2022-12-12T10 in your logs.

$ sudo dmesg --time-format=iso | sed -n '/2022-12-12T09/,/2022-12-12T10/p'


You could alternatively do something like this to add more specificity to the time range (here, we are grabbing only the specified minutes in the range):

In this one, you'd also need a line with 2022-12-12T09:16 and a line with 2022-12-12T09:24 in your logs.

$ sudo dmesg --time-format=iso | sed -n '/2022-12-12T09:16/,/2022-12-12T09:24/p'

From the manpage

--time-format format Print timestamps using the given format, which can be ctime, reltime, delta or iso. The first three formats are aliases of the time-format-specific options. The iso format is a dmesg implementation of the ISO-8601 timestamp format. The purpose of this format is to make the comparing of timestamps between two systems, and any other parsing, easy. The definition of the iso timestamp is: YYYY-MM-DDHH:MM:SS,<-+>.

The iso format has the same issue as ctime: the time may be inaccurate when a system is suspended and resumed.

  • I'm not sure what you are trying to achieve with sed! How do you filter logs only between 9 AM to 10 AM? For example a log that has timestamp 2022-12-12T09:26:19 should be shown. Consider 9 and 10 are arbitrary. This can be between any two dates with possibly different days and hours. – Damon Dec 29 '22 at 17:34
  • I was able to test it. You are basically printing all lines between the two. Did it work for you? – justsomeguy Dec 29 '22 at 22:08
  • For me, it doesn't show any logs between the specified range, although I know there are logs with timestamp in that range. – Damon Dec 30 '22 at 00:31
  • @Damon, updated answer to clarify – justsomeguy Jan 03 '23 at 23:44
0

I wrote a little script to collect logs from a range

while read line; do
        d=$(echo $line | cut -d ',' -f 1)
        if [[ $line =~ ^[[:digit:]] ]] && [[ `date -d "$d" +%s` > `date --date="2 hours ago" +%s` ]]
        then
                echo $line
        fi
done < <(dmesg -T --time-format iso)

This will only show logs since 2 hours ago. until can be scripted using the same logic and a different math. The only problem is, it's slower than dmesg itself.

Damon
  • 13
  • Indeed, Bash while read loop extremely slow compared to cat, why? but this could probably be refactored to use Awk, especially if your date stamps are in a sane machine-readable format. – tripleee Dec 29 '22 at 19:46
  • 1
    I found out even a worse problem! dmesg -T doesn't report the timestamp accurately! It's 12 minutes behind and it could be days according to this: https://serverfault.com/questions/576139/dmesg-time-vs-system-time-time-isnt-correct I will try other solution, thank you all for helping me. – Damon Dec 30 '22 at 00:32