Pipeline 路由到了错误的目的地
通知发错人,通常是目的地在链路里被决定的位置和预期不一样:处理器顺序、匹配之前的标签改写、两个挂载点的作用域差异。
通知发出去了,但发给了错误的人:本该只进值班群的进了全员群、本该被屏蔽的还是响了、 同一条事件收到两遍、或者标签改写完之后反而没人收到。 这类问题的共同点是目的地在链路的哪一步被决定的,和你以为的不一样。
紧急程度按方向判断:多发(发给了不该收的人)是噪音,可以慢慢查; 漏发(该收的人没收到)是盲区,先按 有事件但收不到通知 止血, 再回来查路由。
先看通知记录:这一条是谁发出去的
告警事件 → 打开这条事件 → 通知记录。每条记录都写明了它是哪条通知规则、 哪个媒介发出去的。先把这两个值抄下来,问题范围立刻小一半:
| 通知记录里看到的 | 说明目的地是在哪决定的 |
|---|---|
| 只有一条记录,通知规则不是你想的那条 | 告警规则上挂的通知规则选错了 |
| 有多条记录,通知规则 ID 不同 | 这条规则挂了多条通知规则,它们各发各的 |
| 记录出现在「订阅规则通知」那张表里 | 是订阅扩散出来的副本,不是原规则发的 |
| 记录的渠道显示「屏蔽」 | 命中了「只屏蔽通知」的屏蔽规则 |
| 一条记录都没有,但人收到了消息 | 事件是在 edge 上产生的,见 Edge 与中心失联 |
目的地是在哪一步决定的
规则判定产生事件
│
├─① 告警规则上挂的工作流 ← 改这里的标签,下游所有人都看到
│
├─② 屏蔽规则 ← 用的是 ① 改完之后的标签
│
├─③ 落库;订阅规则在这里扩散出副本
│
└─④ 逐条通知规则(挂几条跑几条,互不影响):
├─ 通知规则上挂的工作流 ← 改这里的标签,只有这一条通知规则看得到
├─ 按 时段 → 级别 → 标签 → 属性 依次匹配
└─ 逐条通知配置选媒介和模板,发送
三个决定目的地的地方,按被误解的频率排序:
- ④ 里的通知配置筛选——真正决定「发给谁」的是这里,不是告警规则上的接收人;
- ① 的标签改写——它改完的标签会被 ② 和 ④ 全程使用;
- ③ 的订阅扩散——它只加不减,原规则该发的照发。
完整模型见 降噪与路由模型。
两个挂载点,作用域完全不同
工作流有两个挂载点,日志里能直接看出是哪一个:processor_by_ 后面跟的
就是 alert_rule 或 notify_rule。
INFO dispatch/dispatch.go:290 processor_by_notify_rule_id:1 pipeline_id:1, pipeline executed, status:success, message:
| 挂在告警规则上 | 挂在通知规则上 | |
|---|---|---|
| 日志里的标识 | processor_by_alert_rule_id:<规则ID> | processor_by_notify_rule_id:<通知规则ID> |
| 改标签影响谁 | 屏蔽规则、订阅、所有通知规则 | 只有这一条通知规则的这一次发送 |
| 丢弃事件的效果 | 事件不落库,谁都收不到 | 只有这一条通知规则不发,别的照发 |
| 丢弃时写通知记录吗 | 不写,只在判定记录里留一个 drop_by_pipeline 阶段 | 写一条失败记录,详情是 processor_by_notify_rule_id:1 pipeline_id:3, drop by pipeline |
每条通知规则拿到的都是事件的一份深拷贝,所以在通知规则 A 的工作流里改标签, 通知规则 B 完全看不到。「我改了标签,为什么另一个群还是老样子」的答案通常就是这一条: 挂错了挂载点。
标签改写发生在匹配之前
这是本页最容易反直觉的一点:两个挂载点上的标签改写,都跑在用它匹配之前。
- 挂在告警规则上的工作流跑完,屏蔽规则才开始判断。所以一个把
env=prod改写成env=production的处理器,会让所有按env=prod写的屏蔽规则集体失效—— 现象是「我明明配了屏蔽,还是响了」; - 挂在通知规则上的工作流跑完,通知配置的标签筛选才开始判断。所以在这里加标签, 是可以用来做路由的:加完的标签下一步就能被筛选用上。
反过来,工作流内部的处理器顺序也一样重要:先改写后丢弃和先丢弃后改写不是一回事。 事件被丢弃之后,后面的处理器一律不跑,执行记录里也不会有它们的输出。
常见根因与确认方法
多发:同一条事件被两条通知规则各发一遍
通知规则之间没有优先级、没有「先匹配到就停」。告警规则上挂了几条通知规则, 就依次跑几条;一条通知规则里配了几条通知配置,每条匹配上都会发。
怎么确认:日志里搜这条事件的哈希,notify rule ids: 会为每条通知规则各打一行:
INFO dispatch/dispatch.go:176 notify rule ids: 1, event: 63bfcd082b52afc11f504509aea89de0
出现几行就是跑了几条。通知记录的条数应该和它对得上。
怎么修:不要靠「删掉一条通知规则」来去重——那会连带影响别的告警规则。 在多余的那条通知配置上加标签筛选或级别筛选,把这类事件排除掉。
改了标签之后屏蔽规则不再命中
怎么确认:打开事件详情看标签那一栏,那是工作流跑完之后的结果;
再打开屏蔽规则的过滤条件,两边逐个键值对比。对不上就是它。
判定记录里那条事件的阶段也不会是 muted。
怎么修:二选一——把屏蔽规则改成按改写后的标签写,或者把改写挪到通知规则的挂载点上 (那样屏蔽规则看到的还是原始标签)。前者更好,因为改写后的标签才是这套系统里的事实。
工作流根本没进去
工作流有自己的生效范围(适用标签、适用属性),不满足就整条跳过。 这跟「跑了但没效果」的排查方向完全相反,先分清。
怎么确认:日志里这四行,措辞固定,直接 grep pipeline_id::
processor_by_notify_rule_id:1 pipeline_id:1, event pipeline not applicable, event: <哈希>
processor_by_notify_rule_id:1 pipeline_id:1, event pipeline is disabled, event: <哈希>
processor_by_notify_rule_id:1 pipeline_id:1, event pipeline not found, event: <哈希>
processor_by_notify_rule_id:1 pipeline_id:1, pipeline executed, status:success, message:
not applicable—— 生效范围没匹配上,这是最常见的一条;is disabled—— 工作流被禁用了(禁用不会解除引用,规则上那一项还在);not found—— 工作流被删了,引用变成了死链;pipeline executed—— 真的跑了,那就去执行记录里看它做了什么。
也可以从 UI 走:工作流 → 执行记录,先把时间范围拉宽(默认只有 6 小时), 用事件 ID 搜。一条记录都没有,就是没进去。
怎么修:把生效范围的条件放宽,或者干脆关掉过滤开关—— 过滤开关关着的时候,所有事件都进来。
通知配置的筛选顺序
匹配是时段 → 级别 → 标签 → 属性依次进行,遇到第一个不匹配就返回。
所以看到 not match severity filter,说明时段那一关已经过了——这个顺序本身就是线索。
怎么确认:四种拒绝原因措辞固定:
event time not match time filter
event severity not match severity filter
event tag not match tag filter
event attributes not match attributes filter
这四行是 ERROR 级别打出来的,但它们是正常的筛选行为,不是故障。 日志里看到一片红不用紧张。
匹配通过时也有一行,notify_config 后面把这条通知配置的全部筛选条件都打了出来,
比翻界面快:
INFO dispatch/dispatch.go:453 notify send timeMatch:true severityMatch:true tagMatch:true attributesMatch:true event:<哈希> notify_config:&{ChannelID:7 TemplateID:181 Params:map[] Type: Severities:[1 2 3] TimeRanges:[] LabelKeys:[] Attributes:[] ChannelIdent: UserNames:[] UserGroupNames:[]}
两个「空」的语义正好相反,是这一节的坑:
TimeRanges:[] 为空表示全时段生效,而 Severities:[] 为空表示永远不匹配。
级别没有「不填即全选」。
确认修好了
不要等下一次真实告警。按这个顺序验:
- 在通知规则的那条通知配置上点「运行测试」,选「历史事件」模式,挑一条真出过问题的事件。 这个模式会先跑一遍匹配条件,不匹配会直接告诉你是哪一条不匹配——正好是本页要验的东西;
- 收到之后回到事件详情 → 通知记录,确认通知规则 ID 和媒介都是你期望的那一组, 并且条数和期望一致(多发问题就看这个数);
- 涉及标签改写的,再去工作流 → 执行记录里打开这条记录,看标签改写节点的前后 diff;
- 涉及屏蔽的,等一条真实事件,确认判定记录里的阶段变成了
muted。
「模拟事件」模式跳过所有筛选,验不了路由,只能验渲染和通道。
收集这些再去提问
- 事件 ID / 哈希,以及完整的通知记录(记录里的目标已脱敏,可以直接给);
- 告警规则上「通知规则」这一项,和每条通知规则里每条通知配置的时段、级别、标签、属性四项;
- 日志里这一时刻按事件哈希过滤出来的全部行,重点是
processor_by_、notify rule ids:、notify send timeMatch:和四种not match; - 工作流的生效范围配置,和这条事件对应的执行记录(含标签前后 diff)。
脱敏:webhook 地址、access token、手机号、邮箱一律替换; 标签的键名要保留(路由就是靠它们判定的),值可以替换成占位符。
下一步
- 完全没收到:有事件但收不到通知
- 试跑对了、线上不对:试跑成功但生产执行失败
- 链路的完整模型:降噪与路由模型
- 工作流怎么配:事件 Pipeline
- 执行记录怎么读:查看 Pipeline 执行记录
- 屏蔽规则的两种方式:屏蔽规则