透過 Script 通知媒介讓夜鶯以本機行程方式執行 Shell/Python/任意可執行腳本,並透過標準輸入(stdin)傳入完整告警事件 JSON。
概述
Script(腳本)通知媒介,用來讓 n9e 行程在本機執行一個外部腳本(Shell / Python / 任意可執行檔),並把告警事件、訊息範本、自訂參數、聯絡方式等以 JSON 字串 透過標準輸入(stdin)一次性傳給腳本。腳本裡可以用任意邏輯做下一步處理:寫檔、呼叫第三方 API、推自建 IM、更新工單……彈性比 HTTP Callback 還高。
- 適用情境:
- 公司內部介面比較複雜,HTTP body 拼不出來;
- 想在通知前做一次本機邏輯(查 CMDB、按時段路由、做去重);
- 想直接
print除錯中間結果。
- 你需要準備:n9e 行程本機的可執行腳本(要麼直接把內容貼進表單,要麼放在固定路徑上)。
- 整個設定分兩步:①在夜鶯新建 Script 通知媒介,寫入腳本內容或路徑 → ②在通知規則裡選擇該媒介。
⚠️ 安全提示:Script 媒介會以 n9e 行程的執行使用者 直接執行你寫入的程式碼,相當於遠端命令執行的入口。請只把這項能力開放給可信的管理員;不要在腳本裡直接拼接事件中的不可信欄位,避免命令注入。
腳本執行機制
無論選「使用腳本」還是「使用路徑」,n9e 在每次觸發通知時的執行流程都一樣:
- 把當前批次的事件、範本算繪結果、參數、聯絡方式打包成一個 JSON 物件;
- 啟動設定好的腳本行程,JSON 透過 stdin 一次性寫入;
- 等待腳本退出,逾時未退出則強制 kill;
- 收集 stdout + stderr 的合併輸出(最多保留 512 位元組,超出截斷)作為通知記錄裡的
details,便於事後排查。
stdin 寫入的 JSON 結構(與 Callback 中 $events 一致):
{
"event": { /* events[0] 的快捷引用,單事件情境常用 */ },
"events": [ /* 當前批次的所有事件,結構同 callback */ ],
"tpl": {
"title": "...",
"content": "..."
},
"params": {
"your_custom_key": "your_custom_value"
},
"sendtos": ["13800000000", "alice@example.com"]
}
event/events:完整告警事件物件(欄位以models.AlertCurEvent為準);tpl:根據通知規則中「訊息範本」算繪後的結果,常見的是tpl.title/tpl.content;params:通知規則裡填的自訂參數;sendtos:當媒介綁定了「聯絡方式」時被注入的目標列表。
第一步:在夜鶯新建 Script 通知媒介
-
登入夜鶯 → 左側選單 通知 → 通知媒介,進入通知媒介列表頁。
-
在左側媒介類型面板中點擊 Script,進入新建頁面(對應 URL
/notification-channels/add?ident=script)。
-
表單分兩塊:基礎設定 + 腳本設定。

區塊 欄位 是否需要改 說明 基礎設定 名稱 需要 例如 自訂腳本通知,在通知規則裡選媒介時看到的就是這個名字基礎設定 啟用 保持開啟 關閉後該媒介不會被發送 變數設定 聯絡方式 可不填 選擇後使用者的「手機/郵件/釘釘帳號」等會以 sendtos陣列形式注入 stdin變數設定 參數設定 可加可不加 自訂參數(如 webhook_url、env),透過 stdin 的params欄位透傳Script 設定 逾時時間 一般保持預設 單位毫秒,預設 5000ms(即 5 秒)。腳本逾時會被強制 kill Script 設定 腳本類型 需要選 二選一:使用腳本(直接寫內容)/ 使用路徑(指向已有檔案) -
選擇 使用腳本 時,下方會出現一個程式碼編輯器,把你的腳本貼進去:

儲存後,n9e 會把腳本寫到當前工作目錄下的
.notify_script_<媒介ID>檔案中(類似.notify_script_25),並chmod 0777,每次執行前會比對內容是否變化、變化時重寫。腳本第一行需要包含 shebang,例如
#!/bin/bash、#!/usr/bin/env python3、#!/usr/bin/env -S node等,否則系統不知道用哪個直譯器。 -
選擇 使用路徑 時,填寫一個絕對路徑,例如
/opt/n9e/etc/scripts/notify.py:這種方式適合腳本邏輯較多、需要版本控制的情境。夜鶯不會替你下發檔案,你需要自己保證 n9e 行程所在主機上該路徑存在、有可執行權限、並能被 n9e 執行使用者存取。
-
點擊左下角 儲存,一條類型為「Script」的通知媒介就建好了。
第二步:在通知規則裡使用該媒介
-
左側選單 通知 → 通知規則 → 新增(或編輯既有規則)。
-
在「通知設定」區域:

- 通知媒介:選擇你剛才建立的 Script 媒介;
- 訊息範本:根據腳本裡要不要用
tpl.title/tpl.content決定。如果腳本只用events,可任意選; - 自訂參數:如果你在媒介的「變數設定」裡加了參數,這裡會出現對應輸入框;
- 適用級別 / 適用時段 / 適用標籤:按需過濾要推送的事件。
-
儲存後,點擊「通知測試」即可發送一條測試事件到腳本。腳本的 stdout/stderr(截斷到 512 位元組內)會回寫到通知歷史裡。
腳本範例
下面給出兩個最常見的腳本範例,可直接複製使用。
範例 1:Python + requests,按業務標籤路由到不同的下游
#!/usr/bin/env python3
import json
import sys
import requests
data = json.load(sys.stdin)
events = data.get("events", [])
if not events:
sys.exit(0)
# 按 tag 路由
ROUTES = {
"team=infra": "https://itsm.example.com/api/n9e/infra",
"team=biz": "https://itsm.example.com/api/n9e/biz",
}
for ev in events:
tags = ev.get("tags_json", {}) or {}
tag_kv = [f"{k}={v}" for k, v in tags.items()]
target = next((url for k, url in ROUTES.items() if k in tag_kv), None)
if not target:
continue
requests.post(target, json=ev, timeout=5)
print("done")
範例 2:把事件寫入本機紀錄檔,方便回溯
#!/bin/bash
mkdir -p /var/log/n9e-notify
cat >> /var/log/n9e-notify/$(date +%F).log
echo >> /var/log/n9e-notify/$(date +%F).log
之後用
tail -f /var/log/n9e-notify/$(date +%F).log就能即時觀察夜鶯給腳本投遞的內容,除錯時非常方便。
常見問題
Q1:腳本沒有執行 / 報 permission denied?
A:分別檢查:
- 選擇「使用路徑」時,對應檔案必須存在且對 n9e 執行使用者具備 執行權限(
chmod +x); - 選擇「使用腳本」時,n9e 會自動
chmod 0777,但前提是它對 當前工作目錄(一般是 n9e 啟動目錄)有寫入權限; - 腳本首行需要正確的 shebang,例如
#!/usr/bin/env python3。
Q2:腳本逾時被 kill?
A:預設逾時 5000ms,對於要請求外部介面的腳本可能不夠。請在 Script 媒介的「逾時時間」裡把毫秒數調大(例如 30000 即 30 秒)。腳本裡也建議自己加 HTTP/請求級逾時,避免被外部慢服務拖死。
Q3:腳本裡的 stdin 收不到內容?
A:n9e 會關閉 stdin 後再等待退出,所以請在腳本裡「讀完 stdin 再處理」。Bash 用 payload=$(cat)、Python 用 json.load(sys.stdin) 即可。如果腳本一啟動就呼叫阻塞讀取(如 read -t 1),可能錯過資料。
Q4:腳本輸出哪去了?怎麼除錯?
A:腳本的 stdout 和 stderr 會被合併儲存到通知歷史的 details 欄位(最多 512 位元組)。日常除錯可以:
- 在腳本裡
echo關鍵變數; - 同時把 stdin 寫到本機紀錄檔(參考範例 2);
- 也可以在 n9e 的 log 裡搜尋
event_script_notify_result,能看到完整的 stdin、命令列和 stdout。
Q5:能不能在容器裡用?
A:可以,但注意:
- 腳本一定要在 n9e 容器內部 存在(寫腳本內容的方式會寫到容器內的工作目錄);
- 如果選「使用路徑」,需要把腳本所在目錄掛載進容器;
- 容器內可能沒有
bash/python3,請安裝好或改用靜態二進位; - shebang 裡的
#!/usr/bin/env xxx需要xxx在PATH裡。
Q6:和 Callback 怎麼選?
A:
- 下游就是一個 HTTP 介面:直接用 Callback,設定最簡單;
- 需要本機處理邏輯(CMDB 查詢、按時段判斷、呼叫多個下游):用 Script,一切在腳本裡搞定;
- 需要把事件存檔到本機檔案 / 佇列:用 Script。
參考資料
- Callback 通用 Webhook(如果只是 POST JSON 到一個 URL,優先用這個)
- 訊息範本說明(如何撰寫
$tpl.title、$tpl.content)