我想要实现的目标:
我想按日期过滤系统日志文件,即当我这样做时:
$ 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
文件)上实现相同的功能?
此外,是否可以过滤:
- 按日期范围?
- 按日期+小时范围?
暗示:如果可能的话,使用“易于记忆的命令”。
答案1
systemd
给我们提供journalctl
如下过滤方式:
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
例子可以合并!
答案2
一般来说,这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
另一个答案中给出的解决方案。)
答案3
有一个方便的日志文件查看器,叫做lnav
,支持多种过滤选项,包括进出过滤器以及时间过滤。
安装:(启用 Universe 存储库)
sudo apt install lnav
要按日期进行过滤,请使用内部命令:
:hide-lines-after <date>
:hide-lines-before <date>
使用以下命令重置日期范围:
:show-lines-before-and-after
这些是通过按下:然后输入命令来调用的,并且可以与任何进出根据关键词进行过滤。
我希望有一种更简单的方法来过滤日期,但目前这似乎是最好的方法。