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?

Edgar Magallon
  • 4,711
  • 2
  • 12
  • 27
Damon
  • 13
  • 4
  • 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 parse `dmesg`. 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.

justsomeguy
  • 374
  • 1
  • 7
  • 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
  • 4
  • Indeed, [Bash `while read` loop extremely slow compared to `cat`, why?](https://stackoverflow.com/questions/13762625/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