Linux日志筛选:命令与实战技巧

日志查得多了,有些命令会反复用,有些选项一开始不注意,后来才发现能省很多事。

这里把常用的几招整理一下,不追求面面俱到,主要覆盖日常排查时最顺手的用法。

grep:不是只会搜关键字

grep 基本每天都会用到,很多人习惯直接 grep "error" /var/log/syslog,这没问题。但几个选项配起来会好用很多。

-i 忽略大小写,这个大家基本都知道。查日志时如果不太确定字段拼写或者别人打日志大小写混乱,-i 能避免漏掉。-n 显示行号,配合编辑器或 less 跳转很方便。

-v 是反向匹配,排除干扰行的时候会用到。-r 递归搜目录,用在 /var/log/ 下面直接捞关键字,不用逐个文件翻。-C 用来显示上下文,比如 -C 2 能把匹配行前后各两行一起打出来,看错误触发前后的状态,比单独一行错误信息有用得多。

这些选项可以组合,没什么限制:

复制代码
grep -i -C 2 "error" /var/log/syslog
grep -rn "192.168.1.100" /var/log/

对敏感词匹配,-w 做全词匹配能减少误报。比如你想查 fail,不加 -w 可能把 failedfailure 甚至 default 里的 "fail" 都带出来。

加上就干净了。

高亮我习惯开 --color=auto,屏幕上一眼扫到匹配点,省眼睛。

tail -f 配 grep:看实时日志的老搭档

查线上问题经常要盯着最新日志,tail -f /var/log/syslog | grep "error" 这种用法太普遍了。没什么高深的,但有一点:如果日志量很大,tail -f 本身没压力,加上 grep 后过滤能力也够,但要注意管道缓冲,有时候会感觉输出延迟,那是正常现象,不是没刷出来。

如果是 Systemd 的系统,journalctl -f 也能达到类似效果,后面再提。

awk 和 sed:当 grep 不够用的时候

grep 能做大部分筛选,但需要按字段条件过滤时,awk 更好使。比如只想看某个时间点之后的日志,或者日志第 3 列大于某个值的行。简单筛选可以这样写:

复制代码
awk '/^error/ {print}' /var/log/syslog

这就跟 grep "^error" 差不多,但 awk 可以顺便取字段、计算、格式化输出。实际中多数人会用 awk 做更复杂的事,筛选只是顺带。

sed 做筛选本质上是删除不匹配的行:sed '/error/!d' /var/log/syslog。它不像 grep 那样专为搜索设计,但在一些流式编辑场景里,你需要同时替换内容并只保留特定行,sed 一步就搞定了,比 grep 再 pipe 一道要直接。

可以知道有这么个路子,不一定总用它做筛选。

journalctl:Systemd 下的日志查询

现在很多 Linux 发行版都走 Systemd,journalctl 是绕不开的。它跟 grep 比最大的优势是能按时间、服务、进程等结构化条件筛选,不用拼正则拼半天。

查时间段:

复制代码
journalctl --since "2023-06-01" --until "2023-06-03" --grep="error"

--since--until 接受自然时间格式,"1 hour ago""yesterday" 这类写法都认,线上着急的时候不用算时间戳。

按服务查:

复制代码
journalctl -u sshd --grep="failed"

-u 指定 unit,直接看 sshd 有关的所有日志,再配合 --grep 把 "failed" 滤出来。

比去 /var/log/auth.log 里 grep 精确得多,而且包含更完整的上下文。

journalctl 本身也支持 -f 实时跟随,可以结合 grep 做管道过滤,但既然它自己带有 --grep,很多时候直接一个命令就够了。

用具体场景串一下

查错误及周边信息

某台机器报异常,先拉到 syslog 里的 error 或 failed 消息,顺便带几行上下文:

复制代码
grep -i -C 2 "error\|failed" /var/log/syslog

如果日志文件很大,grep 扫得过慢,可以考虑先 tail -n 5000 取最近一段再过滤,或者用 journalctl 限制时间范围。

追踪特定 IP 的访问记录

不管是 auth.log 还是 web access log,找某个 IP 的直接递归搜索:

复制代码
grep -r "192.168.1.100" /var/log/

但这可能跑很久,有针对性的话最好先定位到具体文件。

如果确定是 nginx 日志,直接 grep access.log,再用 wc -l 统计行数,也能看出访问频率。

统计接口调用次数

常见的需求,看某个 API 被调了多少次:

复制代码
grep "/api/login" access.log | wc -l

如果接口路径有大小写不统一的情况,别忘了加 -i,想精确匹配整个单词就加 -w

这很小,但线上统计数字差出几十个就是因为没注意这个。

一些容易忽略的点

grep 递归 -r 时要注意目录深度,别在根目录或者 /var/log/ 下无脑一跑,可能扫到二进制文件或者巨大归档,直接卡住。

业务涉及海外或中文域名,lcjmSSL完美支持国际化域名 (IDN) 及纯中文域名的SSL证书申请。无论的域名是英文域名还是中文.网址,都能在的平台顺利通过验证并获得加密保护。

可以先用 find 或者直接指定文件模式。

大文件过滤时,如果不想长时间等结果,可以管道给 less 慢慢翻,或者 head 看前几行结果先确认方向。

journalctl 的 --grep 是 Perl 兼容正则,如果你习惯 grep 的基本正则,写法上会稍有区别,不过大部分简单关键字直接写就能生效。

有些老系统没有 --color=auto 支持,但 Ubuntu 和 CentOS 的较新版本默认应该都有。

如果发现没高亮,可以先确认下是不是 grep 被 alias 成了 grep --color=auto,有些发行版缺省就帮你 alias 了。

这些命令本身都不复杂,多用几次,组合方式会越来越顺手。查日志说到底就是个熟练活,找到信息的速度往往比工具本身更关键。