面对成百上千行的日志文件,漫无目的地翻看只会浪费时间。有效的排查策略都遵循同一个原则:不断缩小范围,直到锁定关键事件。时间、关键词、错误码就是最常用的三个过滤器。
1. 按时间定位:先框定问题发生的窗口
任何故障都有发生的时间点或时间段。先确认问题出现的大致时间,然后只在这个时间范围内查看日志,能立刻将干扰信息排除在外。
- 传统日志文件(如
/var/log/syslog、/var/log/nginx/access.log):
多数日志每一行都以时间戳开头,可以用 grep 结合正则快速过滤。例如查看 2025 年 1 月 15 日 14:30 到 14:40 之间的系统日志:
grep '2025-01-15T14:3[0-9]' /var/log/syslog
若时间戳格式为 Jan 15 14:30,则可这样写:
grep 'Jan 15 14:3[0-9]' /var/log/messages
- 使用
journalctl查看 systemd 日志:
--since 和 --until 参数让时间过滤极其方便:
journalctl --since "2025-01-15 14:30:00" --until "2025-01-15 14:40:00"
还支持相对时间,如 --since "10 minutes ago"。
- 使用
awk按时间戳字段筛选:
当日志时间戳在固定列时(如标准 syslog:Jan 15 14:30:01),可以用 awk 比较:
awk '$1" "$2 >= "Jan 15 14:30:00" && $1" "$2 <= "Jan 15 14:40:00"' /var/log/syslog
框定时间窗口后,日志量通常会大幅缩减,接下来可以进一步用关键词或错误码过滤。
2. 按关键词定位:抓住异常事件的特征描述
日志中的关键词反映具体的行为或状态,例如服务名、动作(error、fail、denied、timeout)、资源名等。
- 基础过滤:
grep -i 'error' /var/log/syslog
-i 忽略大小写,可同时匹配 Error、ERROR 等。
- 多重关键词:
用 grep -E(扩展正则)或管道串联多个 grep:
grep -E 'error|fail|denied' /var/log/nginx/error.log
或者更精细地筛选:
grep 'sshd' /var/log/auth.log | grep 'Failed'
这样可以快速找到 SSH 登录失败记录。
- 排除无关信息:
有时关键词太宽泛会引入大量正常日志,可用 grep -v 反向排除:
grep 'kernel' /var/log/syslog | grep -v 'debug\|DMA'
- 针对特定服务的日志:
许多服务将日志写入独立文件(如 /var/log/mysql/error.log),直接查看这些文件即可,无需全局搜索。
关键词过滤通常能将日志压缩到几十行以内,便于逐行检查。
3. 按错误码定位:精确到具体错误类型
HTTP 状态码、系统错误码、应用返回码是高度结构化的信息,比文字描述更精准,也更适合自动化监控。
- HTTP 状态码:
查找 Web 服务器返回 500 的请求:
grep ' 500 ' /var/log/nginx/access.log
注意空格避免匹配到如“1500”等数字。也可用 awk 按字段精确匹配(假设状态码在第 9 列):
awk '$9 == 500' /var/log/nginx/access.log
- 系统错误码:
内核或系统调用返回的错误码(如 EACCES、ENOSPC、ECONNRESET)通常以符号名或编号形式出现在日志中。例如查找磁盘空间不足的日志:
grep 'No space left on device' /var/log/syslog
或直接搜错误码编号:
grep 'errno 28' /var/log/syslog # 28 对应 ENOSPC
- 应用返回码:
数据库、消息队列等中间件通常会输出明确的错误码,直接搜索该代码即可定位官方文档中的说明。
4. 组合使用:层层收窄,一击即中
实际排查时,通常是先时间→再关键词→最后错误码的渐进过程。例如,要排查昨晚 22:00 左右出现的 Nginx 502 错误:
# 第一步:时间范围框定
grep '22/Jan/2025:22:' /var/log/nginx/access.log > /tmp/access_22.log
# 第二步:错误码筛选
awk '$9 == 502' /tmp/access_22.log
# 或者一步到位:
grep '22/Jan/2025:22:' /var/log/nginx/access.log | awk '$9 == 502'
如果想同时查看同一时刻的错误日志,可结合错误日志文件:
grep '2025/01/22 22:' /var/log/nginx/error.log | grep -i 'upstream\|timeout'
5. 实用技巧与注意事项
- 实时跟踪:排查正在发生的问题时,使用
tail -f实时观察日志,可在另一个终端触发请求,立刻观察日志反应。 - 日志轮转:注意
grep搜索的目标可能已被轮转为压缩文件(如syslog.1.gz),可用zgrep直接搜索.gz压缩包。 - 时间格式统一:不同服务时间格式可能不同(有的带年份,有的不带),组合分析时需先统一格式或分别处理。
- 保留原始日志:排查时尽量复制或过滤到临时文件再操作,避免误改原文件。
- 善用
less翻看:当过滤后的日志仍较多时,用less可翻页、搜索(按/输入关键词),比直接输出到终端更易阅读。 - 使用
journalctl的字段过滤:对于 systemd 日志,可直接按字段过滤,如journalctl _SYSTEMD_UNIT=nginx.service,无需手动 grep。
掌握按时间、关键词、错误码三个维度的组合过滤,你就拥有了通用的日志排查方法论。无论是系统运维还是应用调试,这个思路都能帮你快速从噪音中提取信号,高效定位问题根因。