Webhook 回呼處理器 — 透過 HTTP 將告警事件資訊傳送到外部服務,不會修改事件內容。

概述

Callback 是 Nightingale 告警系統中的一個事件處理器,它允許您透過 HTTP 呼叫將告警事件資訊傳送到外部服務。當告警事件流經此處理器時,處理器會將事件資料以 JSON 格式傳送到指定的 URL,用於通知外部系統或觸發自動化處理流程。與 Event Update 處理器不同,Callback 處理器不會修改事件內容,主要用於事件通知和整合。

工作原理

  1. 事件接收:處理器接收到告警事件
  2. 資料序列化:將事件物件轉換為 JSON 格式
  3. HTTP 呼叫:透過 POST 請求將 JSON 資料傳送到設定的 URL

設定說明

基礎設定

URL(必填)

  • 說明:外部服務的 HTTP 介面位址
  • 格式:完整的 HTTP/HTTPS URL
  • 範例https://your-service.com/api/alert-webhook

進階設定

授權設定

  • 授權使用者名稱:HTTP Basic 認證的使用者名稱
  • 授權密碼:HTTP Basic 認證的密碼
  • 使用場景:當外部服務需要身分驗證時使用

HTTP Headers

  • 說明:自訂 HTTP 請求標頭
  • 格式:鍵值對形式
  • 預設包含Content-Type: application/json
  • 範例
    X-API-Key: your-api-key
    Authorization: Bearer your-token
    X-Custom-Header: custom-value
    

HTTP Proxy

  • 說明:HTTP 代理伺服器位址
  • 格式http://proxy-host:porthttps://proxy-host:port
  • 使用場景:當需要透過代理存取外部服務時

Callback Timeout

  • 說明:HTTP 請求逾時時間
  • 單位:毫秒(ms)
  • 預設值:10000(10 秒)
  • 建議:根據外部服務回應時間適度調整

TLS InsecureSkipVerify

  • 說明:是否略過 TLS 憑證驗證
  • 預設值:關閉(驗證憑證)
  • 注意:僅在測試環境或私有憑證時開啟

外部服務介面規範

您的外部服務需要符合以下要求:

請求格式

  • 方法:POST
  • Content-Type:application/json
  • 請求主體:完整的告警事件 JSON 物件

回應格式

  • 狀態碼:建議傳回 200 表示接收成功
  • 回應主體:選填,回應內容會記錄到 Nightingale 日誌中

事件物件結構範例

{
  "rule_name": "规则名称",
  "severity": 2,
  "tags": [
    "host=server01",
    "service=web"
  ],
  "tags_map": {
    "host": "server01",
    "service": "web"
  },
  "annotations": {
    "summary": "告警摘要",
    "description": "详细描述"
  }
}

使用場景

場景 1:ITSM 工單建立 自動在服務管理系統中建立故障工單。

場景 2:自動化維運 觸發自動化修復指令稿或維運操作。

場景 3:資料同步 將告警資料同步到外部監控或分析系統。

實際使用案例

Python 服務範例

以下是一個使用 Python 標準函式庫的簡單範例,示範如何建立一個外部服務來接收 Callback 請求:

1. 建立 Python 服務檔案(callback_receiver.py)

from http.server import HTTPServer, BaseHTTPRequestHandler
import json
import logging
from datetime import datetime
from urllib.parse import urlparse

# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

class CallbackHandler(BaseHTTPRequestHandler):
    def do_POST(self):
        """Handle POST requests"""
        try:
            # Parse request path
            parsed_path = urlparse(self.path)
            
            if parsed_path.path == '/api/alert-webhook':
                self.handle_alert_callback()
            else:
                self.send_error(404, "Not Found")
                
        except Exception as e:
            logger.error(f"Error handling request: {str(e)}")
            self.send_error(500, "Internal Server Error")
    
    def handle_alert_callback(self):
        """Handle alert callback from Nightingale"""
        try:
            # Read request body
            content_length = int(self.headers.get('Content-Length', 0))
            if content_length == 0:
                self.send_error(400, "Empty request body")
                return
                
            post_data = self.rfile.read(content_length)
            event = json.loads(post_data.decode('utf-8'))
            
            print(json.dumps(event, ensure_ascii=False, indent=2))
            
            response = {
                "status": "success",
                "message": "Alert received and printed"
            }
            
            response_data = json.dumps(response, ensure_ascii=False).encode('utf-8')
            self.wfile.write(response_data)
            
        except json.JSONDecodeError as e:
            logger.error(f"JSON parsing error: {str(e)}")
            self.send_error(400, "Invalid JSON")
        except Exception as e:
            logger.error(f"Error processing event: {str(e)}")
            self.send_error(500, "Internal Server Error")
    
    def log_message(self, format, *args):
        """Custom log format"""
        logger.info(f"{self.address_string()} - {format % args}")

if __name__ == '__main__':
    server_host = '0.0.0.0'
    server_port = 5001
    
    print("Alert callback receiver starting...")
    print(f"Webhook endpoint: http://localhost:{server_port}/api/alert-webhook")
    print("Press Ctrl+C to stop")
    print("=" * 80)
    
    try:
        server = HTTPServer((server_host, server_port), CallbackHandler)
        server.serve_forever()
    except KeyboardInterrupt:
        print("\nStopping service...")
        server.shutdown()
        print("Service stopped")

2. 啟動服務

python callback_receiver.py

服務啟動後會在 http://localhost:5001 監聽請求。

3. 在 Nightingale 中設定

在 Callback 處理器設定頁面中設定:

  • URLhttp://localhost:5001/api/alert-webhook

與 Event Update 處理器的區別

特性 Callback 處理器 Event Update 處理器
主要用途 事件通知和整合 動態更新事件內容
事件修改 不修改事件 可以修改事件
回應處理 僅記錄回應日誌 將回應作為新事件內容
適用場景 工單、整合 事件增強、動態處理

常見問題

Q:如果外部服務無法使用怎麼辦?

A:處理器會記錄錯誤日誌,並繼續傳遞原始事件,不會中斷告警流水線。

Q:支援重試機制嗎?

A:目前版本不支援自動重試,如需重試請在外部服務側實作。

Q:如何除錯設定問題?

A:可以點選頁面上的「測試」按鈕驗證設定,同時檢視 Nightingale 日誌。

Q:回應時間過長怎麼辦?

A:可以適度增加 Timeout 設定,或者最佳化外部服務的回應效能。

注意事項

  • 確保外部服務的高可用性,避免影響告警處理流程
  • 合理設定逾時時間,平衡回應速度與服務穩定性
  • 定期監控外部服務的效能與可用性
  • 在正式環境使用前充分測試設定與外部服務

參考資料

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