跳到主要内容

有事件但收不到通知

有事件但没通知,先看通知记录:没有记录是被屏蔽规则或通知规则拦下,记录失败看媒介配置,记录成功但人没收到看对端。

告警事件页上明明白白有一条事件,钉钉群、邮箱、手机都没动静。 这页顺着事件从产生到发出的真实顺序走一遍,每一步给出「怎么确认卡在这里」。

紧急程度按面判断:单条规则收不到,改规则就行;所有规则都收不到, 先去看通知媒介本身和 n9e_alert_notify_record_queue_size 有没有堆积。

先打开通知记录​

告警事件 → 打开这条事件 → 通知记录。这是整页最省时间的一步: 有没有记录、记录是成功还是失败,直接把问题范围砍成三分之一。

你看到的卡在哪
一条记录都没有事件根本没走到通知这一步,看下面「没有任何通知记录」
有记录,状态是失败走到了发送,发送本身出错,看「有记录但是失败的」
有记录,渠道显示「屏蔽」命中了「只屏蔽通知」的屏蔽规则
有记录,状态成功夜莺这边发出去了,看「显示成功但人没收到」

记录里的目标默认是脱敏的(最后 8 位替换成星号); 短信、语音、邮件、脚本和屏蔽这几类例外,显示原文。

通知记录默认只保留 7 天,每天凌晨 1 点清理。查历史事故要趁早。

链路的真实顺序​

顺序错了就会查错地方。真实顺序是:

规则判定产生事件
│
├─① 规则上挂的工作流(可以直接把事件丢掉)
│
├─② 屏蔽规则
│ · 屏蔽事件与通知(默认)→ 事件根本不产生
│ · 只屏蔽通知 → 事件产生并落库,只是不发
│
├─③ 落库;订阅规则在这里扩散出副本
│
└─④ 逐条通知规则:
├─ 通知规则上挂的工作流(第二个、独立的钩子)
├─ 按级别 / 标签 / 属性 / 时段匹配
└─ 选媒介和消息模板,发送

两个最容易记反的地方:工作流跑在屏蔽之前;工作流有两个挂载点, 一个在告警规则上,一个在通知规则上。

没有任何通知记录​

事件在,通知记录空的。按 ④ 里的顺序往回查:

1. 这条规则挂通知规则了吗。 规则详情里的「通知规则」为空,就没有任何东西会被触发。 这是新建规则最常见的遗漏,媒介测试和通知规则测试都测不出来它。

2. 通知规则是启用的吗。 禁用的通知规则会被静默跳过,日志里什么都不打。

3. 是恢复事件、而恢复通知被关了吗。 日志里会有:

notify_id: 1, event:<哈希>, should skip notify

4. 通知规则上的工作流把事件丢了吗。 这一种会留下一条失败的通知记录, 错误信息长这样:

processor_by_notify_rule_id:1 pipeline_id:3, drop by pipeline

而告警规则上的工作流丢弃事件时不写通知记录(那时候还没进入通知阶段), 只在判定记录里留一个 drop_by_pipeline 阶段。

5. 匹配条件把它过滤掉了。 这是最常见的一种,而且不写通知记录,只写日志。 四种拒绝原因,措辞固定,直接 grep:

event time not match time filter
event severity not match severity filter
event tag not match tag filter
event attributes not match attributes filter

特别注意级别:通知配置里一个级别都不勾,等于永远不匹配—— 它没有「不填即全选」的语义。这条规则漏掉的通知,界面上看不出任何异常。

匹配成功时也有一行,可以用来确认确实走到了这一步:

notify send timeMatch:true severityMatch:true tagMatch:true attributesMatch:true event:<哈希> notify_config:...

6. 改完配置多久生效。 通知规则、消息模板、媒介的缓存都是 9 秒刷新一次, 改完立刻测有可能还在用旧的。

有通知记录,但是失败的​

记录里的详情就是原因,照着对:

详情含义
notify_channel not found媒介被删了、或者被禁用了
message_template not found这条通知配置没选消息模板
failed to enqueue notify task, queue is full这个媒介的发送队列满了(每媒介 10 万条),下游卡住了
all retries failed, last error: ...连都连不上,是网络或地址问题
status_code:400, response:...对方收到了但拒绝了内容——一般是 token、签名或消息格式
failed to execute template: ...模板渲染失败,见 通知模板渲染失败

关于 message_template not found 有一个例外要知道: callback、flashduty、pagerduty 这三类不消费消息模板,缺模板不会被拦; 其余媒介缺模板会整条丢弃并写一条失败记录。 注意 callback 是按媒介标识 callback 放行的,你自己复制一份改了标识的 callback 媒介 不在豁免之列。

通知记录显示成功,人却没收到​

这一段最反直觉,但恰恰是最常见的报障。

HTTP 类媒介只把「HTTP 200」算成功,而且完全不看响应体。 钉钉返回 200 + {"errcode":310000,"errmsg":"keywords not in content"} 这种, 在通知记录里是成功。所以第一件事是把记录里的 response: 那一段读完—— 答案通常就写在里面。

顺带两个也算成功、但含义不同的:201 / 202 / 204 会被当成失败(只认 200); 而只有传输层错误才重试,任何一个 HTTP 响应都是一次就返回。

按媒介类型,还有几条各自的脾气:

  • FlashDuty:不管对方返回什么状态码,一律记成功(这是刻意设计,避免重试打乱对端数据)。 只能靠记录里的响应体判断,status_code: 后面是几就是几。
  • PagerDuty:200 和 202 算成功,其余状态码会重试,默认共 4 次。
  • 邮件:通知记录里渠道恒为 Email、成功时详情恒为字面量 success, 不是对方 SMTP 的响应。而且成功入队时不写记录,只有真正发送失败才写; 更绕的一点是:第一次失败、重试成功的情况,记录里仍然是失败。 邮件要以收件箱为准,不要以记录为准。
  • 企业微信带截图时:文本和图片是两次请求,图片那次失败会让整条判失败。

如果记录里响应体也正常,就是对端的问题了:群机器人的关键词/IP 白名单、 邮件进了垃圾箱、手机号不在接收人列表里。用 媒介的「测试」按钮再发一条, 直接看对端有没有收到,能把边界划清楚。

订阅规则不会替你止损​

订阅是加一份通知,从来不会减少原规则的通知。所以「订阅了但没收到」和 「原规则也没收到」是两个独立问题,各查各的。

一个容易踩的点:订阅规则如果没有选通知规则,订阅出来的那份副本就不会走 v9 的通知链路, 等于订阅了个寂寞。订阅产生的通知记录会归在事件详情的「订阅规则通知」那张表里。

收集这些再去提问​

  1. 事件 ID,以及通知记录的完整内容(记录里的目标已脱敏,可以直接给);
  2. 规则详情里「通知规则」这一项,和通知规则里每条通知配置的级别勾选、标签过滤、时段;
  3. 日志里这一时刻的 notify_id:、notify send timeMatch:、not match 三类行;
  4. curl -s http://127.0.0.1:17000/metrics | grep n9e_alert_notify_record_queue_size。

脱敏:webhook 地址、access token、签名密钥、手机号、邮箱一律替换; 响应体里的 errmsg 要保留(它就是答案)。

下一步​