通用 Callback
通过通用 Callback 通知媒介把告警事件以 JSON 形式 POST 到任意自定义 Webhook 地址,可对接 IM 机器人、ITSM、内部运维平台等。
概述
Callback(回调)是一个通用的 HTTP Webhook 通知媒介,用于把夜莺产生的告警事件以 JSON 形式 POST 到任意一个 URL。除了系统内置的钉钉、企业微信、飞书等媒介之外,绝大多数自定义对接都可以用 Callback 完成:例如对接公司内部的 ITSM/工单系统、自研运维平台、自建机器人、Logstash/Loki 等数据通道,或者把事件转发到 Flashduty、PagerDuty 之类的下游告警平台。
- 适用场景:对接任意 HTTP 接口,且需要直接拿到完整的告警事件 JSON。
- 你需要准备:一个能被夜莺访问的 HTTP/HTTPS URL(可写在通知规则里,按规则切换)。
- 整个配置分两步:①保留默认的 callback 通知媒介(或新建一个) → ②在通知规则里填入
callback_url。
与钉钉、企业微信等媒介不同,Callback 默认 不渲染消息模板,请求体直接就是
{{ jsonMarshal $events }},也就是事件原始结构的 JSON 数组。如果对方需要拿模板渲染后的 Markdown 文本,可在请求体里改用{{$tpl.content}}等变量,参考下文"自定义请求体"。
第一步:确认/新建 Callback 通知媒介
夜莺安装后会自带一个名为 Callback 的内置媒介,通常不需要修改即可使用。如果你需要按业务区分多个 Callback 媒介(例如一个发到 ITSM、一个发到自研平台),可以再新建一个:
-
登录夜莺 → 左侧菜单 通知 → 通知媒介,进入通知媒介列表页。
-
在左侧媒介类型面板中点击 回调,进入新建页面(对应 URL
/notification-channels/add?ident=callback)。
-
表单中绝大部分字段已经预置好,只需要改一下"名称":

区块 字段 是否需要改 说明 基础配置 名称 需要 例如 内部 ITSM 回调,在通知规则里选媒介时看到的就是这个名字基础配置 启用 保持开启 关闭后该媒介不会被发送 变量配置 联系方式 可不填 一般 Callback 不需要按用户区分;如果需要把用户的手机号/邮箱注入到 body,可在这里选择对应字段 变量配置 参数配置 保持默认,不要删 已预置 callback_url、note两个参数,真正的目标 URL 由通知规则里填的callback_url决定HTTP 配置 URL 保持默认 {{$params.callback_url}},会被通知规则里填的值替换HTTP 配置 请求方法 POST默认即可,也可改成 PUT/GETHTTP 配置 请求头 Content-Type: application/json默认已填好,按需追加鉴权头(如 Authorization: Bearer ...)HTTP 配置 超时/并发/重试 一般保持默认 默认 10s 超时、5 并发、3 次重试,间隔 100ms -
继续向下可以看到"请求体",这段是 Callback 的核心:

默认请求体只有一行:
{{ jsonMarshal $events }}含义:把本次要通知的所有事件序列化成一个 JSON 数组,整体作为 body POST 出去。下游可以拿到事件的全部字段(
id、rule_name、severity、tags、annotations、first_trigger_time、last_eval_time、is_recovered等),按需解析处理。 -
点击左下角 保存,一条类型为"回调"的通知媒介就建好了。
第二步:在通知规则里填入 callback_url
-
左侧菜单 通知 → 通知规则 → 新增(或编辑已有规则)。
-
在"通知配置"区域:

- 通知媒介:选择刚才创建的(或内置的)Callback 媒介;
- 消息模板:默认请求体里没有用到
$tpl,所以任意模板都可以,建议保留为空或选Default;如果你在请求体里改用了{{$tpl.title}}/{{$tpl.content}},那么这里需要选择对应模板; - Callback Url:填写要回调的目标 URL,例如
https://itsm.example.com/api/v1/n9e/webhook,必须以http://或https://开头; - Note:可选,自定义备注,不会进入请求;
- 适用级别 / 适用时段 / 适用标签:按需过滤要推送的事件。
-
保存后,点击"通知测试"即可发送一条测试请求,下游接口应能收到一段 JSON 数组。
默认请求体里 $events 的 JSON 结构(节选)
[
{
"id": 12345,
"rule_id": 100,
"rule_name": "CPU 使用率过高",
"severity": 2,
"is_recovered": false,
"first_trigger_time": 1714377600,
"last_eval_time": 1714377900,
"trigger_value": "85.6",
"tags": ["ident=host01", "region=cn-bj"],
"tags_json": {"ident": "host01", "region": "cn-bj"},
"annotations": "{\"summary\":\"...\"}",
"target_ident": "host01",
"cluster": "default"
}
]
完整字段以
models.AlertCurEvent为准。如果你的下游只需要少量字段,可以参考"自定义请求体"这一节裁剪。
自定义请求体
默认 body 是 {{ jsonMarshal $events }},你可以替换成任意 JSON/表单格式,并在其中嵌入夜莺的内置变量:
| 变量 | 含义 |
|---|---|
$events |
当前批次的事件数组(推荐配合 jsonMarshal 使用) |
$event |
$events 中的第一个事件(单事件场景) |
$tpl |
经过消息模板渲染后的内容,例如 {{$tpl.title}}、{{$tpl.content}} |
$params |
通知规则里填入的自定义参数,例如 {{$params.callback_url}}、{{$params.note}} |
$sendto、$sendtos |
当前发送目标(如手机号、邮箱);当媒介绑定了"联系方式"时才会被注入 |
示例 1:发送渲染后的 Markdown 到 Slack 兼容接口
{
"text": "{{$tpl.title}}\n{{$tpl.content}}"
}
示例 2:转发为 Flashduty 风格的事件
{
"event_status": "{{if $event.IsRecovered}}Ok{{else}}Critical{{end}}",
"alert_key": "{{$event.Hash}}",
"title_rule": "{{$event.RuleName}}",
"description": "{{$tpl.content}}"
}
示例 3:批量上报到自建系统
{{ jsonMarshal $events }}
选择哪种 body,取决于下游接口期望的格式。如果对方期望表单,可把
Content-Type改成application/x-www-form-urlencoded,并按key1=val1&key2=val2写。
常见问题
Q1:发完没反应、下游也没收到,怎么排查?
A:登录夜莺 → 在告警事件详情页查看通知记录,可以看到每次回调的 HTTP 状态码和响应体。常见原因:
- URL 未带协议头(必须以
http:///https://开头); - 服务端要求鉴权,请在"请求头"里追加
Authorization; - 服务端 IP 白名单未放通夜莺所在主机出口 IP;
- 请求超时,可在 HTTP 配置里把
超时时间调大。
Q2:下游想要的是单个事件而不是数组?
A:默认 body 是 {{ jsonMarshal $events }},会发数组。如果想发单个事件,把 body 改成 {{ jsonMarshal $event }},并在通知规则里关闭聚合发送(或把聚合粒度调低),保证一次回调只带一个事件。
Q3:一个 Callback 媒介能不能给不同业务发到不同的 URL?
A:可以。无需新建媒介,只要在"通知规则"里新增一条规则、填写不同的 callback_url 即可。