From 4b4007db6cf85bac291dad7ee5f1c0f334ab43c6 Mon Sep 17 00:00:00 2001 From: OG T Date: Sun, 5 Apr 2026 14:11:59 +0800 Subject: [PATCH] =?UTF-8?q?feat(telegram):=20SRE=20=E7=BE=A4=E7=B5=84?= =?UTF-8?q?=E5=91=8A=E8=AD=A6=E6=A0=BC=E5=BC=8F=E5=8D=87=E7=B4=9A=E7=82=BA?= =?UTF-8?q?=E5=AE=8C=E6=95=B4=20v7.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit _send_approval_card_to_group 改用與個人 chat 相同的 TelegramMessage.format() 格式,包含 SignOz metrics、AI provider/model、Nemotron 協作、異常頻率統計等全部欄位。 統帥指示:群組收到的告警訊息要與個人 chat 格式完全一致。 Co-Authored-By: Claude Sonnet 4.6 --- apps/api/src/services/telegram_gateway.py | 94 ++++++++++++++++++++--- 1 file changed, 84 insertions(+), 10 deletions(-) diff --git a/apps/api/src/services/telegram_gateway.py b/apps/api/src/services/telegram_gateway.py index 50dbc5cb..112f4310 100644 --- a/apps/api/src/services/telegram_gateway.py +++ b/apps/api/src/services/telegram_gateway.py @@ -1394,6 +1394,7 @@ class TelegramGateway: ) # 2026-04-03 ogt: 發到 SRE 群組並觸發 AI 雙向討論 (Triumvirate ADR-053) + # 2026-04-05 ogt: 升級為完整 v7.0 格式,與個人 chat 一致 # 非同步執行,失敗不影響告警主流程 if settings.SRE_GROUP_CHAT_ID: asyncio.create_task( @@ -1403,6 +1404,27 @@ class TelegramGateway: resource_name=resource_name, root_cause=root_cause, suggested_action=suggested_action, + estimated_downtime=estimated_downtime, + primary_responsibility=primary_responsibility, + confidence=confidence, + namespace=namespace, + signoz_rps=signoz_rps, + signoz_rps_trend=signoz_rps_trend, + signoz_error_rate=signoz_error_rate, + signoz_p99_latency=signoz_p99_latency, + signoz_latency_trend=signoz_latency_trend, + signoz_trace_url=signoz_trace_url, + auto_tuning_command=auto_tuning_command, + ai_tokens=ai_tokens, + ai_cost=ai_cost, + anomaly_frequency=anomaly_frequency, + ai_provider=ai_provider, + ai_model=ai_model, + nemotron_enabled=nemotron_enabled, + nemotron_tools=nemotron_tools, + nemotron_validation=nemotron_validation, + nemotron_latency_ms=nemotron_latency_ms, + incident_id=incident_id, ) ) @@ -1415,23 +1437,75 @@ class TelegramGateway: resource_name: str, root_cause: str, suggested_action: str, + estimated_downtime: str = "~30s", + primary_responsibility: str = "COLLAB", + confidence: float = 0.0, + namespace: str = "default", + signoz_rps: float = 0.0, + signoz_rps_trend: str = "stable", + signoz_error_rate: float = 0.0, + signoz_p99_latency: float = 0.0, + signoz_latency_trend: str = "stable", + signoz_trace_url: str = "", + auto_tuning_command: str = "", + ai_tokens: int = 0, + ai_cost: float = 0.0, + anomaly_frequency: dict | None = None, + ai_provider: str = "", + ai_model: str = "", + nemotron_enabled: bool = False, + nemotron_tools: list[dict] | None = None, + nemotron_validation: str = "", + nemotron_latency_ms: float = 0.0, + incident_id: str = "", ) -> None: """ - 發送告警卡片到 SRE 群組並觸發 AI 討論 + 發送告警卡片到 SRE 群組 — 與個人 chat 相同的完整 v7.0 格式 + 2026-04-05 ogt: 升級為完整格式(含 SignOz/AI/Nemotron),移除精簡版 由 asyncio.create_task 非同步呼叫,失敗不影響主告警流程。 """ try: - # 2026-04-03 ogt: 選項 C 區塊式格式(老闆指示) - # 2026-04-03 ogt: 老闆指示移除自動 AI 分析,告警只發卡片 - risk_emoji = RISK_EMOJI_MAP.get(risk_level.lower(), "⚪") - summary = ( - f"【{risk_emoji} {risk_level.upper()}】{html.escape(resource_name[:40])}\n\n" - f"📋 {html.escape(approval_id)}\n" - f"🔍 {html.escape(root_cause[:150])}\n" - f"🔧 {html.escape(suggested_action[:80])}" + emoji = RISK_EMOJI_MAP.get(risk_level.lower(), "⚠️") + + signoz_metrics = None + if signoz_rps > 0 or signoz_error_rate > 0 or signoz_p99_latency > 0: + signoz_metrics = SignOzMetricsBlock( + rps=signoz_rps, + rps_trend=signoz_rps_trend, + error_rate=signoz_error_rate, + p99_latency_ms=signoz_p99_latency, + latency_trend=signoz_latency_trend, + trace_url=signoz_trace_url, + ) + + message = TelegramMessage( + status_emoji=emoji, + risk_level=risk_level.upper(), + resource_name=resource_name, + root_cause=root_cause, + suggested_action=suggested_action, + estimated_downtime=estimated_downtime, + approval_id=approval_id, + incident_id=incident_id, + primary_responsibility=primary_responsibility, + confidence=confidence, + namespace=namespace, + signoz_metrics=signoz_metrics, + signoz_trace_url=signoz_trace_url, + auto_tuning_command=auto_tuning_command, + ai_tokens=ai_tokens, + ai_cost=ai_cost, + anomaly_frequency=anomaly_frequency, + ai_provider=ai_provider, + ai_model=ai_model, + nemotron_enabled=nemotron_enabled, + nemotron_tools=nemotron_tools, + nemotron_validation=nemotron_validation, + nemotron_latency_ms=nemotron_latency_ms, ) - await self.send_to_group(text=summary) + text = message.format_with_nemotron() if nemotron_enabled else message.format() + await self.send_to_group(text=text) except Exception as e: logger.error("send_approval_card_to_group_failed", error=str(e))