一次线上故障,把 2000 行日志贴给助手,它说"看起来是连接池耗尽"。而实际原因是"某条 SQL 变慢导致连接被长时间占用"——连接池耗尽只是结果。团队按第一个假设查了四十分钟,最后才回到日志里那句 Slow query: 12.3s。
AI 在日志分析上确实很强:提取关键字、发现异常时间点、列出可能原因。但它的输出是"假设",而排障要的是"证据"。这个区别在排障里是"方向性"的:顺着一个错的假设查十分钟,等于十分钟的净损失;而"验证一个证据"无论如何都产生信息(哪怕结论是"不是它")。
区别在于:假设可以错,证据必须能验证。
1. 它能做的三件事
| 任务 | 可信度 |
|---|---|
| 提取关键行(错误、超时、异常值) | 高(文本匹配) |
| 找时间相关性(A 与 B 同时出现) | 中高 |
| 提出可能原因 | 中(可能是错的方向) |
第三项最容易被当成"结论",而它实际上只是"一个待验证的猜测"。第三项的"语言伪装"很强:"连接池耗尽导致超时"读起来像分析,实际是猜测——因为"导致"这两个字没有被任何日志行支持。
第一项的"正确用法"是"先让它挑行,再自己读那 15 行":于是"人的注意力"被集中到关键处——而这比"让它给结论"有用得多。
第一项的价值常被低估:2000 行日志里,真正有用的可能只有 15 行——而"找出这 15 行"是纯文本问题,模型做得很好。
2. "假设"与"证据"的差别
| 项 | 假设 | 证据 |
|---|---|---|
| 形式 | "可能是 X" | "在 T 时刻,X 出现了 Y 值" |
| 能否验证 | 需另找数据 | 已在内 |
| 错了怎么办 | 换个假设 | 说明前一步判断错 |
所以"让它给假设"没问题,问题在"把假设当证据用"——而它在语言上毫无区别(都很像分析)。
3. 三类它容易"想错"的地方
| 类型 | 例子 |
|---|---|
| 把伴随当因果 | "连接池满" 与 "SQL 慢" 同时出现 |
| 忽略缺失证据 | 日志里没有 GC 记录,就说"GC 正常" |
| 过度归纳 | 三条错误 → "某个模块不可靠" |
第一项是"因果倒置":**连接池满通常是"结果"**第一项的"判别方法"很直接:问"为什么这个值会变成这样"。连接池满 → 因为连接被占用 → 因为查询慢 → 因为索引缺失——每问一层,就离"原因"近一步。
,而"原因"可能是"某个查询变慢"。
第二项的"防法"是"让它列'这份日志里有哪些字段/事件类型'":于是你能看出"GC 日志不在这份里",而不是"GC 正常"。
第二项最危险:"没看到"不等于"没有"——而模型会把"日志里没出现"当成"没发生"。
// 一次典型误判(同一份日志)
模型:"连接池耗尽,建议加大池大小。"
实际:慢查询 12.3s(日志第 1180 行),连接被占用 12 秒 → 池被耗尽
正确动作:先优化慢查询;加池只是推迟问题
// 判别:问"连接为什么被占用这么久",答案在"慢查询"那行
4. 正确的用法:三段式
| 阶段 | 谁做 |
|---|---|
| 1 提取异常行 | 助手(文本筛选) |
| 2 排时间线 | 助手(相关性) |
| 3 判定因果 | 人(需要系统知识) |
| 4 设计验证 | 人 + 助手(生成查询/命令) |
第三项不能交给它:因果判断需要"系统怎么工作"的知识,而那不在日志里。第三项的"分工"可以更具体:人负责"哪些因果可能"(拓扑、依赖、变更),助手负责"日志支持哪一条"——于是两边各自做擅长的部分。
第四项的"质量"取决于"它知不知道你的环境":知道(K8s、MySQL 版本、监控系统)时给的是命令;不知道时给的是"通用建议"——所以"给环境信息"是提示的关键部分。
第四项是它最有价值的地方之一:"怎么验证这个假设" 它往往能给出一串可执行的检查(查什么指标、跑什么命令)。
"提取异常行"这一步可以给具体规则,比"看看有什么异常"有效得多:
// 提取规则(写进提示,四类)
1 时间窗口内 level=ERROR/WARN 的行
2 耗时分位数异常的行(如 > P99 的请求)
3 首次/末次出现的关键事件(起止边界)
4 与"上下游服务名"相关的行(超时、连接失败)
// 要求:每行给"行号 + 原文摘要",不要概括
5. 提示该怎么写
| 要素 | 作用 |
|---|---|
| 给"时间窗口"与"服务拓扑" | 缩小范围 |
| 明确"不要给结论,只列假设 + 依据" | 防止"自信误判" |
| 要求"每个假设给出验证方法" | 可执行 |
| 要求"标出"日志里没有的信息" | 防"缺失当没有" |
第四项很关键:让它显式说"这份日志里没有 X 的记录"第四项的"实现"是一条提示要求:"对每个你无法从日志确认的项,写'未见相关记录'"。于是"缺失"变成可见信息,而不是"默认正常"。
,于是你知道"它没看到",而不是"它认为 X 正常"。
// 提示模板(四段)
上下文:服务 A(3 实例)在 14:02–14:35 出现 5xx 上升;下游 B/C。
任务:只做"提取异常行 + 排时间线 + 列假设",不要下结论。
要求:每个假设附"支持它的日志行号"与"如何验证"。
边界:如果某项信息这份日志里没有,请明确写"未见相关记录"。
"验证清单"可以要求它按"成本"排序,于是排障顺序自动变合理:
// 让它为每个假设给"验证成本"
假设:连接池耗尽
验证 A:查池的活跃/等待数(一条指标查询,10 秒)
验证 B:查是否有慢查询(慢日志一条命令,30 秒)
验证 C:抓线程栈看谁持有连接(jstack,1 分钟)
// 要求:"按验证成本从低到高排序,先做 A"
6. 排错:五种"AI 分析误导"
| 现象 | 成因 | 处理方向 |
|---|---|---|
| 顺着错的假设查很久 | 假设当结论 | 要求"依据行号" |
| 加了资源没解决 | 治标不治本 | 问"为什么被占用" |
| 漏掉了关键行 | 日志太长 | 让它先"提取异常行" |
| 结论与另一份日志矛盾 | 只给了一份 | 给全量或说明缺失 |
| 复查时无法解释 | 无时间线 | 让它排时间线 |
第五项(复查时无法解释)在"复盘"时最要命:没有时间线,就无法回答"为什么当时选了这个方向"——于是复盘的结论只能是"下次注意"。
第一项的"成本"很具体:四十分钟的方向性错误,而它本可以在"给行号"这一步被避免。
最后一个"时间线"的产出格式,值得固定下来(否则它的输出无法用于复盘):
// 时间线(四列,直接贴进故障单)
时刻(UTC) 事件/日志摘要 来源 精度
13:41 首批投诉 工单 分钟
14:02 连接池活跃 20/20,等待 0 指标 秒
14:05 Slow query 12.3s(orders) 慢日志 秒
14:31 重启实例 A 发布系统 秒
// 关键:每行标"来源与精度",于是"可复核"而不是"看起来对"
7. 边界:什么情况不必用 AI 分析日志
| 场景 | 为什么 | 做法 |
|---|---|---|
| 错误信息已明确指出原因 | 无需推断 | 直接查 |
| 日志量小(< 100 行) | 自己看得完 | 自己看 |
| 涉密日志 | 不能外发 | 脱敏或不用 |
| 已有成熟告警与看板 | 信息已结构化 | 看板优先 |
判断口径一句话:"日志量"是否超过"人能扫一遍"的量。最后一条与"能力"有关的边界:AI 在"日志分析"上的价值随"日志量"线性增长,而它的错误率不随日志量下降。所以"日志越多越该用它挑行,而不是越该信它的结论"。
超过(几千行、多服务),AI 的"提取与排序"价值很大;不超过,自己看更快。
8. 自测
- 它能做的三件事里,哪一件最容易被当成结论?
- "假设"与"证据"的区别是什么?为什么两者在语言上难以区分?
- 三类"容易想错"里,哪一类最危险?"日志里没有"为什么不等于"没发生"?
- 三段式里,哪一步不能交给它?为什么因果判断需要"日志之外的知识"?
- 提示里为什么要"要求标出日志里没有的信息"?
- 判断"是否需要 AI 分析日志"的那个问题是什么?