From ea78d0814bd0e19667dbfd1ac50fca68ca8f12b3 Mon Sep 17 00:00:00 2001 From: OoO Date: Sat, 2 May 2026 13:08:00 +0800 Subject: [PATCH] refactor(telegram): migrate alert_routes sender to EventRouter (ADR-019 Phase 5) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit routes/alert_routes.py 的 send_telegram_message() 是 Alertmanager webhook 通用告警 出口,原本直接 POST sendMessage 並對每個 chat_id 迴圈。改走 services.event_router. dispatch_sync() 統一入口(event_type=alertmanager_webhook, severity=alert)。 行為變化: - 移除手動 chat_id 迴圈,改傳 admin_chat_ids 給 EventRouter(內部仍逐一發) - 新增 ADR-012 三層分流(L0/L1/L2)+ JSONL queue replay 失敗重送 - parse_mode 參數保留簽名向後相容,但實際統一走 EventRouter HTML 模板 - caller(Alertmanager webhook handler)的 try/except 結構未動 Co-Authored-By: Claude Opus 4.7 (1M context) --- routes/alert_routes.py | 48 ++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/routes/alert_routes.py b/routes/alert_routes.py index 04bc176..265b625 100644 --- a/routes/alert_routes.py +++ b/routes/alert_routes.py @@ -96,31 +96,37 @@ def check_alert_auth(f): def send_telegram_message(message: str, parse_mode: str = 'HTML') -> bool: - """發送 Telegram 訊息""" + """ + 發送 Telegram 訊息 + + ADR-019 Phase 5: 改走 EventRouter 統一入口,享 retry + JSONL queue replay。 + parse_mode 參數保留向後相容(EventRouter 內部統一 HTML,舊 caller 若指定 + 其他 mode 會被忽略;此 route 原本就只用 HTML,影響面=0)。 + """ if not TELEGRAM_BOT_TOKEN or not TELEGRAM_CHAT_IDS: logger.warning("[Alert] Telegram 未設定,無法發送告警") return False - success = True - for chat_id in TELEGRAM_CHAT_IDS: - try: - url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/sendMessage" - payload = { - 'chat_id': chat_id, - 'text': message, - 'parse_mode': parse_mode - } - response = requests.post(url, json=payload, timeout=10) - if response.status_code != 200: - logger.error(f"[Alert] Telegram 發送失敗: {response.text}") - success = False - else: - logger.info(f"[Alert] Telegram 訊息已發送到 {chat_id}") - except Exception as e: - logger.error(f"[Alert] Telegram 發送錯誤: {e}") - success = False - - return success + try: + from services.event_router import dispatch_sync + result = dispatch_sync(event={ + "event_type": "alertmanager_webhook", + "severity": "alert", + "source": "Alertmanager.Webhook", + "title": "Alertmanager 告警", + "summary": message[:400], + "status": "received", + "payload": {"raw_message": message, "parse_mode": parse_mode}, + }, admin_chat_ids=TELEGRAM_CHAT_IDS) + delivered = bool(result.get("delivered")) + if not delivered: + logger.error(f"[Alert] EventRouter 告警未送達: {result.get('errors')}") + else: + logger.info(f"[Alert] EventRouter 告警已派送 sent={result.get('sent')}") + return delivered + except Exception as e: + logger.error(f"[Alert] EventRouter dispatch 失敗: {e}") + return False def format_alert_message(alert: dict, status: str) -> str: