20

What I want to achieve:

I'd like to filter a system log file by date, i.e. when I do:

$ cat /var/log/syslog | grep -i "error\|warn\|kernel" 

it prints lines like these for the three last days let say:

(...)
Apr  3 06:17:38 computer_name kernel: [517239.805470] IPv6: ADDRCONF(NETDEV_CHANGE): wlp3s0: link becomes ready
(...)
Apr  4 19:34:21 computer_name kernel: [517242.523165] e1000e: enp0s25 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: None
(...)
Apr  5 09:00:52 computer_name kernel: [517242.523217] IPv6: ADDRCONF(NETDEV_CHANGE): enp0s25: link becomes ready

How to grep (select, or filter):

  • by date?
  • by date+hour?

What I tried:

$ cat /var/log/syslog | grep -i "Apr  5" | grep -i "error\|warn\|kernel" 

It works as expected on the syslog file, but not on the kern.log file for example, which only returns: Binary file (standard input) matches. And when I tail this particular file I can see the same starting date format than in the syslog file.

Question:

How to achieve the same on other logs like the kern.log file?

In addition, is it possible to filter:

  • by date range?
  • by date+hour range?

Hint: if possible, with "easy-to-remember commands".

3 Answers 3

27

systemd gives us journalctl which allows filtering like this:

journalctl --since "2 days ago"  
journalctl --since "today"
journalctl --since "yesterday --until "today" 
journalctl --since "2019-03-10" --until "2019-03-11 03:00"
journalctl -b # since last boot 
journalctl -k # kernel messages
journalctl -p err # by priority like (emerg|alert|crit|err|warning|info|debug)
journalctl -u sshd # for a particular unit 
journalctl _UID=1000 # for a particular user id

Examples can be combined!

2
  • 5
    Ok now this is so cool! Apr 5, 2019 at 8:44
  • 2
    Often not even sudo is required (in particular if the user is member of the adm group, which the "main" user usually is).
    – PerlDuck
    Apr 5, 2019 at 9:32
6

In general, the kern.log is a text file. But sometimes it happens that it contains some binary data, especially when the system has crashed before and the system could not close the file properly. You may then notice lines containing text like ^@^@^@^@^@^@^@^@^@ and such.

If grep notices its input is binary, it usually stops further processing and prints ... binary file ... instead. But there's a switch to change this behaviour. From the manpage:

[...]
File and Directory Selection
   -a, --text
          Process a binary file as if it were text; 
          this is equivalent to the --binary-files=text option.
[...]

You can try the following:

$ grep -a -i "Apr  5" /var/log/kern.log  | grep -i "error\|warn\|kernel"

(But I would actually prefer the journalctl solution given in another answer.)

0

There is a handy log file viewer called lnav, that supports many filtering options, including in/out filters, as well as time filtering.

Install with: (have Universe repository enabled)

sudo apt install lnav

To filter on dates, use the internal commands:

:hide-lines-after <date>
:hide-lines-before <date>

Date ranges are reset with the command:

:show-lines-before-and-after

These are invoked by pressing : and then typing the command, and can be combined with any in/out filters on keywords.

I wish there were an even easier way to filter on dates, but currently this seems to be the best way.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .