告警配了一堆却没人看:让 AI 重写监控规则的排查顺序

2026-07-29

数据截至 2026-07,各产品的额度与报错口径以官方最新说明为准。

告警没人看,绝大多数时候不是”覆盖不够”,而是”这条告警响的时候,收到的人不知道该做什么”。 这两种病因的处置方向正好相反:前者要加规则,后者要删规则、并给每条活下来的规则补上处置动作。团队最常见的失误是把后者误判成前者,于是让 AI 一口气生成几十条规则灌进去,三周后所有人都学会了滑走通知——你等于花力气训练了团队忽略告警。

先说清楚这篇和站内相邻两篇的分工:Agent 可观察日志怎么打 讲的是上游,怎么让运行过程留下能被机器读的痕迹;日志里的敏感信息怎么办 讲的是这些痕迹的合规边界。本篇接在它们后面,只管一件事:这些信号怎么变成”值得把人叫醒”的告警规则,以及规则失效时按什么顺序排查。

一、先分因:告警失效有四种,别混着治

在动手改任何规则之前,先判断你处在哪一类。这四类的现象很像,成因完全不同。

现象大概率成因怎么验证处置动作
告警群整天响,值班的人已经不看了阈值是拍脑袋定的,正常波动就能触发取最近四周的告警记录,统计每条规则触发次数,以及其中被标记为”需要人工干预”的比例触发多但干预率极低的规则,直接降级为看板指标或周报,不再发通知
真出事时告警来得比用户投诉晚监控的是结果指标而不是先行指标把最近几次事故的时间线摊开,标出用户反馈时刻和告警时刻的先后补一条更靠前的信号(错误率斜率、队列积压、依赖方超时比例),结果指标只做兜底
告警响了但没人知道该干什么规则里只有条件没有处置说明,接手人不在同一上下文随机抽三条历史告警,问一个没参与过该模块的同事”看到这条你第一步做什么”每条告警强制带上:影响面一句话、第一步验证命令、升级对象
同一次故障炸出几十条告警缺少依赖关系抑制,底层故障沿调用链扩散看那批告警的时间戳是否集中在同一分钟内、是否指向同一依赖建立抑制关系:底层组件告警触发期间,上层派生告警合并或静默

这张表的用法是先定位再动手。你要是同时得出两个以上结论,说明还没查清楚,继续往下拆,不要一次改四件事——改完你分不清是哪一改起了作用。

二、AI 能帮到哪一步,哪一步必须人来定

我把这一环拆成六个动作,界线其实很清楚。

AI 做得比较稳的三件事。把历史告警归类:把脱敏后的告警记录丢给模型,让它按同一根因聚类并给出每类典型样本,比人肉翻工单快,也不容易漏掉低频但反复出现的那几类。把已定好的判断逻辑翻译成规则语法:你说清”错误率连续五个采样周期高于基线的两倍且请求量不低于日常低谷”,让它写成你所用监控系统的表达式,这是纯翻译活。写处置说明:给它一条规则加上架构描述,让它产出”先看什么、再看什么、什么情况下升级”,人再删改,比从空白页开始省事。

必须人来定的三件事,交出去就会出事。一是什么算事故。 一个接口的失败率在什么水平上算需要把人从床上叫起来,这是业务判断,取决于这个接口背后是支付还是推荐。模型没有你的赔付条款和客户名单,它给的阈值只是常见做法的平均值。二是告警的收件人与升级路径。 谁被叫醒、多久没人认领要升级给谁,涉及职责和排班,写错了后果是事故期间无人认领。三是抑制与静默的边界。 静默范围一旦定宽,下一次真正的独立故障会被一起吞掉。这类”少报”的代价远高于”多报”,必须由熟悉依赖关系的人签字。

还有一件事经常被忽略:AI 生成的规则表达式要过一遍语法校验和空跑,不能直接上线。模型对监控查询语言的时间窗口语义、聚合维度容易写出语法正确但语义错位的东西,比如把按实例聚合写成了全局聚合,结果单实例挂了永远不触发。

三、按顺序动手:从一条告警的下游倒推上游

改造顺序反着来最省事,从”人收到之后做什么”倒推回”条件怎么写”。

第一步,给每条现存规则补一行”响了之后第一个动作是什么”。 写不出来的,说明这条告警对处置没帮助,先关掉发通知的通道。这一步通常能砍掉一半以上的规则,而且几乎没有风险——你只是不再打扰人,指标还在采集。

第二步,为活下来的规则各配一条验证命令。 命令要能在三十秒内跑完并给出是非判断,例如探活:

curl -s -o /dev/null -w '%{http_code} %{time_total}\n' \
  --max-time 5 https://example.com/healthz
echo "curl exit=$?"

这里有个容易写错的细节:请求根本没拿到 HTTP 响应时,%{http_code} 打出来的是 000 而不是空字符串,超时、DNS 解析不出来、连接被对端重置,三种情况在这一行输出里长得一模一样。真正能把它们分开的是 curl 的退出码,所以验证命令里一定要把退出码一起打出来(上面那行 echo),并在处置说明里写清各码对应哪种情况——具体数值以你机器上 man curl 的 EXIT CODES 一节为准,不同版本会有增补。这三种情况的处置方向完全不同:超时多半是后端慢或链路拥塞,解析失败要去看 DNS 和服务发现,连接被重置常常是中间的网关或防火墙动了手脚,把它们混成一条”服务不可用”,值班的人第一步就会走错。

拿到了 HTTP 状态码的情况同样要分。涉及凭据的服务,401 与 403 要分开写:一个是没带上凭据,一个是带了但没权限,后者往往意味着有人改了策略而不是服务挂了,去重启服务是白费力气。5xx 里也别只写”服务端错误”,网关自身返回的 502/504 和应用返回的 500,排查的入口一个在网关一个在应用日志。验证命令的判据写得越细,交接的时候越省口舌。

第三步,确定阈值时用历史数据反推,而不是先定数字。 拿一段没出过事的时间窗,算出指标的分位数分布,再看你打算设的条件在这段时间里会触发几次。会触发的次数就是你未来的噪音量。这段统计用最普通的脚本就够:

import statistics

# vals 是从监控系统导出的同一指标的历史采样序列
vals = [...]
vals.sort()
p95 = vals[int(len(vals) * 0.95)]
print("p95 =", p95, "median =", statistics.median(vals))

模型可以帮你解释这些分布代表什么、建议用哪种统计口径,但按下”就用这个值”的必须是你。

第四步,把规则纳入版本管理,改动走评审。 监控配置最怕的是有人在界面上临时点了个静默然后忘了取消。规则文件进仓库之后,git log -p --follow alerts/api-latency.yml--follow 只接受单个文件路径,别省掉)就能回答”这条阈值上次是谁改的、为什么改”。评审里只看三样:条件语义、通知对象、失效方式(这条规则在数据缺失时是触发还是不触发)。

第五步,把成本类指标一并纳入。 用了模型 API 的系统,异常往往先反映在调用量和失败重试上,口径参考 API 成本监控怎么做。限流类响应(429)不该配成立即叫人,它是常态波动的一部分,持续超过某个窗口才升级更合适——各家服务的限流规则不同且会调整,以官方最新说明为准。

四、验收:怎么证明这套告警是活的

改完之后不做验收,等于没做。四个动作,都能在一个迭代内跑完。

故意制造一次可控失败。 在预发环境把某个依赖的地址指向一个不可达端口,看告警是否在你预期的时间内到达、内容是否说清了影响面。做完记得恢复,并检查静默有没有残留。

做一次交接测试。 找一个不在这个模块的同事按告警内容独立处置一次,全程你不解释。他卡在哪一步,那一步的说明就是不合格的。

统计干预率。 对每条规则算”触发次数中真正导致人工操作的比例”。这个比例长期极低的规则,就是训练大家忽略告警的元凶。分类口径可以借用 Agent 失败怎么分类 里的思路,把”需要人介入”和”系统自愈”分成两条统计线。

验证失效方式。 把数据源停掉,看那条规则是安静地不触发,还是能报出”数据缺失”。多数团队栽在前者:监控挂了,告警系统一片祥和。这条一定要单独测。

五、什么时候别再折腾:止损点和回滚点

监控改造很容易变成无底洞,给自己划三条线。

止损点一:同一条规则调阈值超过三次仍然噪音不降,就换指标而不是继续调数字。 反复调阈值说明这个指标本身跟你关心的故障不相关,再精确的数字也救不回来。换一个更贴近用户感受的指标(成功率、端到端耗时的高分位),比继续微调有用。

止损点二:改造两周后总告警量没降,但事故发现时间也没缩短,停下来复盘方向。 这两个数一起不动,通常意味着你在优化告警系统,而问题出在服务本身缺少可观测信号——上游没埋点,下游怎么配都是猜。

回滚点:新规则上线后如果出现漏报,立刻回滚到上一版规则文件,而不是在新版上打补丁。 多报是可以忍的,漏报不行。规则进了仓库,回滚就是一条 git revert,成本很低,别舍不得。

换条路的信号:如果你发现真正难的是”判断这次异常要不要叫人”,而不是”怎么把条件写出来”,那你需要的其实是人工确认环节,不是更聪明的规则。 让系统在拿不准的时候把判断交给人,比追求全自动判定现实得多,这条思路在 生产事故里 AI 的边界 里展开过。

六、避坑清单

用 AI 一次性生成整套规则再全量上线。 会踩是因为生成的东西看起来都对,语法没问题、命名规范、注释齐全,人很难有耐心逐条审。避的办法是限量:一次只上三条,跑满一个值班周期,看干预率再决定下一批。生成速度快不等于验证速度快,瓶颈从来在后者。

让模型顺手把阈值也定了。 会踩是因为你不给数字它也会给,语气还很笃定。它给的是常见做法的平均值,跟你的流量形状无关。避的办法是只让它输出表达式结构,数字留空位,由你用历史分布填。

把重试中的瞬时错误配成立即告警。 会踩是因为日志里确实出现了报错,看起来该管。但如果重试成功了,这只是正常的抖动吸收。避的办法是只对”重试耗尽后仍失败”配告警,并确认重试逻辑本身是幂等的,否则你会把重复执行当成正常。

告警内容里带上原始请求体或响应体方便排查。 会踩是因为排查确实需要上下文,随手就贴进去了。但告警会进入群聊、邮件、第三方通知服务,这条链路的留存和权限跟你的日志系统完全不同。避的办法是告警里只放定位坐标(追踪 ID、时间窗、服务名),详情让人回系统里查,脱敏口径见前面提到的敏感信息那篇。

静默期设置得比故障恢复时间长。 会踩是因为处置时被刷屏烦到,顺手静默一个较长的时间。避的办法是静默必须填原因和到期时间,并且每周有人扫一遍现存静默项,把过期没清的清掉。这个动作定时跑一次比靠自觉可靠。

本地验证规则时忽略环境差异。 会踩是因为本地的实例数量、流量形状跟线上差一个量级,聚合维度的问题在本地暴露不出来。避的办法是规则里显式写清聚合维度,并在预发用接近线上的实例数跑一次。环境变量注入的地址差异也常见,上线前确认一次:

env | grep -i -E 'endpoint|host|url'

海外托管的监控或模型服务直接写进线上链路。 需要提醒的是,部分海外工具与模型的官方服务对中国大陆有区域限制、不支持直连,把它放在告警链路的关键位置,会让你的监控本身成为不稳定项。市面上存在第三方中转,这里不作背书也不给具体渠道;真要用,至少让告警的主通道不依赖它。另外这类跨境链路上的自签证书或代理中间人会导致证书链校验失败,排查时容易误判成服务不可用。

收个尾

告警系统的价值不在覆盖率,在于每一次响铃都换来一个动作。AI 在这一环是很好的翻译器和归类器,但阈值、收件人、静默边界这三样是判断题,判断题没法外包——这是我的看法,你可以按自己团队的排班现实调整。

上线前对着这份清单过一遍:

  • 每条会发通知的规则,都写得出第一个处置动作了吗?
  • 阈值是从历史分布反推的,还是拍的?
  • 数据源断了的时候,这条规则是安静还是报警?
  • 告警内容里有没有塞进不该出群的原始数据?
  • 同一次故障的派生告警有抑制关系吗?
  • 规则改动在仓库里有记录、能一条命令回滚吗?
  • 现存的静默项,每一条都有到期时间和原因吗?

六条以上答得上来,你的告警才开始有资格占用别人的注意力。

想系统学会用 AI?报名体系课或加入会员,照着学、照着用。