透過通用 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 預設即可,也可改成 PUTGET
    HTTP 設定 請求標頭 Content-Type: application/json 預設已填好,按需追加驗證標頭(如 Authorization: Bearer ...
    HTTP 設定 逾時/併發/重試 一般保持預設 預設 10 秒逾時、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 即可。

參考資料

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