通用 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、一个发到自研平台),可以再新建一个:

  1. 登录夜莺 → 左侧菜单 通知 → 通知媒介,进入通知媒介列表页。

  2. 在左侧媒介类型面板中点击 回调,进入新建页面(对应 URL /notification-channels/add?ident=callback)。

    通知媒介入口

  3. 表单中绝大部分字段已经预置好,只需要改一下"名称":

    Callback 通知媒介表单

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

    HTTP 配置和请求体

    默认请求体只有一行:

    {{ jsonMarshal $events }}
    

    含义:把本次要通知的所有事件序列化成一个 JSON 数组,整体作为 body POST 出去。下游可以拿到事件的全部字段(idrule_nameseveritytagsannotationsfirst_trigger_timelast_eval_timeis_recovered 等),按需解析处理。

  5. 点击左下角 保存,一条类型为"回调"的通知媒介就建好了。

第二步:在通知规则里填入 callback_url

  1. 左侧菜单 通知 → 通知规则 → 新增(或编辑已有规则)。

  2. 在"通知配置"区域:

    通知规则中填写 Callback URL

    • 通知媒介:选择刚才创建的(或内置的)Callback 媒介;
    • 消息模板:默认请求体里没有用到 $tpl,所以任意模板都可以,建议保留为空或选 Default;如果你在请求体里改用了 {{$tpl.title}}/{{$tpl.content}},那么这里需要选择对应模板;
    • Callback Url:填写要回调的目标 URL,例如 https://itsm.example.com/api/v1/n9e/webhook,必须以 http://https:// 开头;
    • Note:可选,自定义备注,不会进入请求;
    • 适用级别 / 适用时段 / 适用标签:按需过滤要推送的事件。
  3. 保存后,点击"通知测试"即可发送一条测试请求,下游接口应能收到一段 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 即可。

参考资料

更新时间 2026-04-29

快猫星云 联系方式 快猫星云 联系方式
快猫星云 联系方式
快猫星云 联系方式
快猫星云 联系方式
快猫星云