按日期或日期范围过滤任何系统日志文件


12

我要实现的目标:

我想按日期(即执行时)过滤系统日志文件:

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

最后三天,它会打印这样的行:

(...)
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

如何grep(选择或过滤):

  • 按日期?
  • 按日期+小时?

我试过的

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

它可以按预期在syslog文件上运行,但不能在kern.log文件上运行,例如,该文件仅返回:Binary file (standard input) matches。当我tail看到这个特定文件时,可以看到与文件中相同的开始日期格式syslog

题:

如何在其他日志(如kern.log文件)上实现相同功能?

另外,是否可以过滤:

  • 按日期范围?
  • 按日期+小时范围?

提示:如果可能,请使用“易于记忆的命令”。

Answers:


14

使用systemd,我们得到了journalctl,它可以轻松地进行如下所示的细粒度过滤:

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

例子可以结合起来!


5
好吧,这太酷了!
乔治·乌德森

2
通常甚至sudo都不需要(特别是如果用户是adm组的成员,而“主要”用户通常是该组的成员)。
PerlDuck

4

通常,kern.log是文本文件。但是有时会发生其中包含一些二进制数据的情况,特别是在系统之前崩溃并且系统无法正确关闭文件的情况下。然后,您可能会注意到包含诸如此类的文本的行^@^@^@^@^@^@^@^@^@

如果grep注意到它的输入是二进制的,则通常会停止进一步的处理并打印... binary file ...。但是可以改变这种行为。从联机帮助页

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

您可以尝试以下方法:

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

(但实际上,我更喜欢journalctl另一个答案中给出的解决方案。)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.