这条工作流解决什么
日志排查的效率取决于顺序,而不是命令有多复杂:先用时间窗把范围缩小一个数量级,再按关键词过滤,接着做频次统计找出高频错误,最后用「同一时间窗、同一单元、同一来源」把孤立条目串成线索。journalctl、grep、awk、sort、uniq 组合起来就够用,不需要额外工具。
基本信息
| 适用场景 | 服务报错、访问异常、联调问题需要从海量日志里找线索 |
|---|---|
| 常用组合 | journalctl 定时间窗与单元,grep 过滤,awk 取字段,sort 加 uniq -c 做频次 |
| 核心原则 | 先缩时间窗,再过滤内容;先看频次,再看个例 |
| 输出格式 | 接管道时加 --no-pager,避免分页控制字符混入 |
| 替代路线 | 结构化日志(JSON)直接上 jq,比文本管道更快更准 |
典型使用场景
- 故障复盘:把两小时的日志缩到故障前后三分钟,命中率立刻提高
- 找出错误大户:按错误信息聚类统计,先修数量最多的那一类
- 追单个来源:以某个 IP 或某个请求 ID 为线索拉出完整时间线
- 定位首次出现:找到异常第一次出现的时间点,再往前推触发条件
- 确认发布影响:对比发布前后的错误频次与新增的错误类型
示例一:错误频次排行
示例一:错误频次排行
journalctl --since '2 hours ago' -p err --no-pager \
| awk '{print $5,$6,$7,$8,$9}' \
| sort | uniq -c | sort -rn | head -n 15 # 高频错误排在最前示例二:追单个来源
示例二:追单个来源
journalctl --since today --no-pager | grep '203.0.113.9' | tail -n 50
journalctl --since today --no-pager | grep -c '203.0.113.9' # 先确认量级
journalctl --since today --no-pager | grep '203.0.113.9' | cut -c1-15 | uniq -c # 看时间分布示例三:异常首现时间
示例三:异常首现时间
journalctl --since today -u myapp --no-pager | grep -n -i -m1 'exception'
journalctl --since today -u myapp --no-pager | sed -n '1,3p' # 确认日志起点
journalctl -u myapp --since '2026-10-13 02:10' --until '2026-10-13 02:20' --no-pager # 锁定窗口细看管道各段作用
| 命令 | 作用 | 常见陷阱 |
|---|---|---|
| journalctl --since | 按时间窗裁剪 | 时区不一致会漏数据,注意应用可能写 UTC |
| -p err | 按优先级过滤 | 只看 err 会漏掉 warn 级的先兆信息 |
| awk '{print ...}' | 取固定字段做归类 | 字段位置随 journalctl 输出格式变化 |
| grep | 关键词定位 | 默认区分大小写,日志里大小写常混用 |
| sort 加 uniq -c 加 sort -rn | 统计频次并排序 | 必须先 sort 再 uniq,顺序反了统计不准 |
| head | 只看前几条 | 会让上游收到 SIGPIPE 提前退出,属正常现象 |
排障先定时间窗再看内容:把两小时的日志缩到三分钟窗口,命中率立刻上升。用 --since 与 --until 精确到分钟,比事后用 grep 捞时间戳更可靠,因为多行日志(堆栈)的时间戳只出现在第一行。
管道里的 grep 默认块缓冲,实时性差,要边跑边看就加 --line-buffered。对持续追加的日志(tail -f)做管道,下游的排序与统计永远不会输出结果,因为输入流没有结束——这类场景要先固定时间窗或先落盘再分析。