从日志里读出故障现场
把散落的日志收成一条时间线,分清证据和猜测
你是排查线上故障的工程师。下面是一段时间的日志,可能混有多个服务。请:1)按时间排出事件链,标出第一个异常点;2)把「日志直接证明的」和「你推测的」分两栏列出;3)指出还缺哪条日志才能定论;4)给出下一步最小验证动作。不要从第一条 ERROR 开始讲,先找它之前发生了什么。 [日志片段/时间范围/相关服务]
使用建议
先把时间统一到同一时区再贴;最贵的线索通常是第一个变慢或超时的请求,而不是第一条 ERROR。
适合什么场景
- 结账延迟从 200 ms 跳到 4 s,大盘却是绿的,用户已经开始报错。
- 只有单个客户的请求失败,整体错误率几乎没动,需要从日志里找出差异。
不适合的场景
- 手上只有一段栈信息,没有 request id、时间戳和前后文:先补日志,不是先分析。
- 已经确定是某个配置写错、只需要改回来:直接修,不必做时间线。
示例
输入
2026-03-14T02:11:03Z api ERROR upstream timeout path=/checkout uid=8821 2026-03-14T02:11:04Z api WARN pool wait 1980ms active=20 idle=0 2026-03-14T02:11:05Z api ERROR upstream timeout path=/checkout uid=8821 2026-03-14T02:11:07Z db slow query 4.2s sql=SELECT ... FOR UPDATE
你会得到
第一个异常是 02:11:03 的 timeout,但时间线的转折点在 02:11:04 的连接池等待:active=20、idle=0,且已有请求等了 1980 ms,说明连接在 timeout 之前就已被占满,timeout 只是结果。慢查询 4.2 s 出现在后面,更像连接被占住后的结果,日志也没给出锁等待对象,不能据此断言是 DB。需要补连接池配置和 `lock wait` 行,才能区分「池太小」和「查询变慢」。
常见误用
- 只贴 ERROR 行,把 WARN 和慢查询丢掉:真正的起因通常就在这两类里。
- 不给时间范围和实例,只让它「分析一下原因」:它会把不同机器的日志拼成一条并不存在的因果链。
可以这样改
- 加「按服务分组再对齐时间」,多服务日志不会被误读成单机上的串行事件。
- 要求「每条结论后面附原文行号」,一眼就能看出哪些是证据、哪些是脑补。