跳到主要内容

Pipeline 路由到了错误的目的地

通知发错人,通常是目的地在链路里被决定的位置和预期不一样:处理器顺序、匹配之前的标签改写、两个挂载点的作用域差异。

通知发出去了,但发给了错误的人:本该只进值班群的进了全员群、本该被屏蔽的还是响了、 同一条事件收到两遍、或者标签改写完之后反而没人收到。 这类问题的共同点是目的地在链路的哪一步被决定的,和你以为的不一样。

紧急程度按方向判断:多发(发给了不该收的人)是噪音,可以慢慢查; 漏发(该收的人没收到)是盲区,先按 有事件但收不到通知 止血, 再回来查路由。

先看通知记录:这一条是谁发出去的​

告警事件 → 打开这条事件 → 通知记录。每条记录都写明了它是哪条通知规则、 哪个媒介发出去的。先把这两个值抄下来,问题范围立刻小一半:

通知记录里看到的说明目的地是在哪决定的
只有一条记录,通知规则不是你想的那条告警规则上挂的通知规则选错了
有多条记录,通知规则 ID 不同这条规则挂了多条通知规则,它们各发各的
记录出现在「订阅规则通知」那张表里是订阅扩散出来的副本,不是原规则发的
记录的渠道显示「屏蔽」命中了「只屏蔽通知」的屏蔽规则
一条记录都没有,但人收到了消息事件是在 edge 上产生的,见 Edge 与中心失联

目的地是在哪一步决定的​

规则判定产生事件
│
├─① 告警规则上挂的工作流 ← 改这里的标签,下游所有人都看到
│
├─② 屏蔽规则 ← 用的是 ① 改完之后的标签
│
├─③ 落库;订阅规则在这里扩散出副本
│
└─④ 逐条通知规则(挂几条跑几条,互不影响):
├─ 通知规则上挂的工作流 ← 改这里的标签,只有这一条通知规则看得到
├─ 按 时段 → 级别 → 标签 → 属性 依次匹配
└─ 逐条通知配置选媒介和模板,发送

三个决定目的地的地方,按被误解的频率排序:

  1. ④ 里的通知配置筛选——真正决定「发给谁」的是这里,不是告警规则上的接收人;
  2. ① 的标签改写——它改完的标签会被 ② 和 ④ 全程使用;
  3. ③ 的订阅扩散——它只加不减,原规则该发的照发。

完整模型见 降噪与路由模型。

两个挂载点,作用域完全不同​

工作流有两个挂载点,日志里能直接看出是哪一个: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:[] 为空表示永远不匹配。 级别没有「不填即全选」。

确认修好了​

不要等下一次真实告警。按这个顺序验:

  1. 在通知规则的那条通知配置上点「运行测试」,选「历史事件」模式,挑一条真出过问题的事件。 这个模式会先跑一遍匹配条件,不匹配会直接告诉你是哪一条不匹配——正好是本页要验的东西;
  2. 收到之后回到事件详情 → 通知记录,确认通知规则 ID 和媒介都是你期望的那一组, 并且条数和期望一致(多发问题就看这个数);
  3. 涉及标签改写的,再去工作流 → 执行记录里打开这条记录,看标签改写节点的前后 diff;
  4. 涉及屏蔽的,等一条真实事件,确认判定记录里的阶段变成了 muted。

「模拟事件」模式跳过所有筛选,验不了路由,只能验渲染和通道。

收集这些再去提问​

  1. 事件 ID / 哈希,以及完整的通知记录(记录里的目标已脱敏,可以直接给);
  2. 告警规则上「通知规则」这一项,和每条通知规则里每条通知配置的时段、级别、标签、属性四项;
  3. 日志里这一时刻按事件哈希过滤出来的全部行,重点是 processor_by_、notify rule ids:、 notify send timeMatch: 和四种 not match ;
  4. 工作流的生效范围配置,和这条事件对应的执行记录(含标签前后 diff)。

脱敏:webhook 地址、access token、手机号、邮箱一律替换; 标签的键名要保留(路由就是靠它们判定的),值可以替换成占位符。

下一步​