LabHub
学习 学习路径 课程

从日志里找原因

没有日志,本身也是情报

在 LabHub 中继续学习

一句话总结

没有日志并不意味着调查结束。工作还包括用其他痕迹缩小时间范围,并确保下次事故发生时能够留下日志。

概念图: 其他痕迹 · 数据本身就是日志。 · 空白区间 · 确保同样的问题再次发生时,比这次更早知道。

为什么需要它

收到“昨天下午有几条请求失败”的报告后,我们开始寻找日志。但日志保留期只有 24 小时,可能已经被删除;日志级别可能是 WARN,所需信息从未记录;或者该路径本来就没有任何日志语句。

如果此时以“没有日志,无法确认”结束调查,同样的事情还会重复发生。

日志之外的痕迹

痕迹 能告诉我们什么 检查方法
文件 mtime 何时修改了什么 find /etc -mmin -1440 -type f
数据库时间戳 数据创建或修改的时间 created_at, updated_at 的分布
进程启动时间 何时发生重启 ps -eo pid,lstart,cmd
系统启动时间 服务器何时启动 uptime -s
文件大小变化 何时突然增长 比较多个备份快照
软件包安装时间 何时安装了什么 /var/log/dpkg.log, rpm -qa --last
Shell 历史 人员执行了什么 ~/.bash_history(启用时间记录时)
证书有效期 因过期引发故障的时间 openssl x509 -noout -dates

**数据本身就是日志。**按分钟聚合失败订单的 created_at 分布,即使没有日志,也能定位事故开始的具体分钟。

SELECT date_trunc('minute', created_at) AS m, count(*)
FROM orders WHERE status='FAILED' AND created_at >= now() - interval '2 days'
GROUP BY 1 ORDER BY 1;

结果中数值突然升高的位置就是事故时间。再把该时间与部署记录、配置变更和启动时间对照,候选原因就会缩小到一两个。

“不存在”本身也是证据

日志中的空白区间本身就是信息。

不要把“没有记录”翻译成“不知道”。询问“究竟什么没有被记录”,范围就会缩小。

为下一次留下证据

调查结束并找到原因后,最后一项工作是确保同样的问题再次发生时,比这次更早知道。

  1. 增加日志语句——在失败路径中记录什么失败、为什么失败,同时记录事后调查所需的值,例如请求 ID、目标和耗时。
  2. 调整保留期限——24 小时不足以支持大多数调查,至少应让错误日志保留更久。
  3. 关联 ID——为每个请求附加 ID,使其能够跨系统追踪。缺少它时,只能通过时间勉强对齐多个服务的日志。
  4. 增加一个指标——把本次问题转化为计数器或仪表,下次就能直接在图表中看到。

把这四项写进报告的“防止复发”部分,就不再是一句形式化描述,而会真正为下一次调查节省数小时。

事后加装观测——问题正在发生时

如果问题当前仍在持续却没有日志,就在能够复现期间附加观测。

这些方法虽然粗糙,却远胜于什么都没有,而且该文件可能成为下次会议中唯一的依据。

第一次为他人的系统添加观测时

FDE 进入客户现场时,系统通常没有日志,或者即使存在也无法查看。在既没有权限、也不能随意部署的状态下,存在一套以最少变更获得最多信息的顺序

**第一,寻找已有信息。**增加新观测前,先清点系统已经留下的内容:Web 服务器访问日志、数据库慢查询日志、负载均衡器统计、云流量日志。它们往往已经启用,只是无人查看。

第二,从外部测量。即使无法修改代码,也可以从外部发起请求。每隔几分钟调用一次核心路径,并记录响应时间和状态码,仅凭这些信息就能知道事故从何时开始。即使不了解原因,知道时间也已经完成了调查的一半。

**第三,在边界添加观测。**即使无法修改应用,通常仍有机会调整前方的代理或 Sidecar。让它按请求记录时间和状态,就能在不修改一行代码的情况下获得请求级观测。

第四,最后才修改代码。进行到这一步时,已经知道应该在哪里加装观测。如果一开始就动代码,可能会监控错误的位置,还要额外承担回滚修改的成本。

**一开始就确定哪些内容应该记录、哪些不应该记录。**面对他人的系统时,很容易在不了解个人信息内容的情况下开启日志。启用完整请求正文记录前,必须先确认正文中包含什么。

**报告时应同时写出数字及其来源。**不要只写“很慢”,而应写“该路径 p95 为 4.2 秒,过去 7 天按负载均衡器统计的中位数为 0.4 秒”。这样下一步行动可以当场确定。缺少来源时,人们会先重新争论数字本身。

生产现场中的表现

后续实验要做什么

你将接手一个事故区间错误日志已经消失的现场,仅凭数据的 created_at、访问日志中的空白区间和配置文件修改时间,把事故时间缩小到分钟级,并将候选原因缩小为一个。

最后还会亲自制作事后观测器。评分程序会实际运行它,确认时间与观测值是否按周期留下记录。