From 167e115a6dcfd88ba683057bbf3dc3a2841437b8 Mon Sep 17 00:00:00 2001 From: OG T Date: Fri, 10 Apr 2026 16:07:56 +0800 Subject: [PATCH] =?UTF-8?q?feat(phase31):=20Log=20=E7=95=B0=E5=B8=B8?= =?UTF-8?q?=E6=91=98=E8=A6=81=E8=A7=B8=E7=99=BC=E9=BB=9E=20=E2=80=94=20?= =?UTF-8?q?=E5=91=8A=E8=AD=A6=E5=BE=8C=20NemoTron=20=E7=99=BC=20log=20summ?= =?UTF-8?q?ary?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit _send_log_summary: 取 Pod log → deepseek-r1:14b 分析 → NemoTron 發到群組 觸發點: _push_decision_to_telegram 送完審批卡後異步執行 Co-Authored-By: Claude Sonnet 4.6 --- apps/api/src/services/decision_manager.py | 39 +++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/apps/api/src/services/decision_manager.py b/apps/api/src/services/decision_manager.py index 3bfc2b64..daf6f84e 100644 --- a/apps/api/src/services/decision_manager.py +++ b/apps/api/src/services/decision_manager.py @@ -41,6 +41,41 @@ logger = structlog.get_logger(__name__) PLAYBOOK_SIMILARITY_THRESHOLD = 0.85 # 相似度 >= 85% 直接使用 Playbook +# ============================================================================= +# Phase 31 (ADR-067 2026-04-10): Log 異常摘要 — NemoTron deepseek-r1:14b +# ============================================================================= + +async def _send_log_summary(incident: "Incident") -> None: + """ + 非同步取得 Pod log 異常摘要,用 NemoTron bot 發到 SRE 群組 + 觸發點:_push_decision_to_telegram 發完審批卡後 + """ + try: + target = incident.affected_services[0] if incident.affected_services else None + if not target: + return + namespace = "awoooi-prod" + if incident.signals: + namespace = incident.signals[0].labels.get("namespace", "awoooi-prod") + + from src.services.log_summary_service import get_log_summary_service + svc = get_log_summary_service() + summary = await svc.summarize_with_soft_timeout(pod_name=target, namespace=namespace) + if not summary: + return + + from src.services.telegram_gateway import get_telegram_gateway + tg = get_telegram_gateway() + await tg.send_as_nemotron( + f"📋 Log 異常摘要{target}\n{summary}" + ) + import structlog as _sl + _sl.get_logger(__name__).info("log_summary_sent", target=target, incident_id=incident.incident_id) + except Exception as e: + import structlog as _sl + _sl.get_logger(__name__).warning("log_summary_failed", error=str(e)) + + # ============================================================================= # Telegram 推送 (Phase 6.5: 決策就緒通知) # ============================================================================= @@ -200,6 +235,10 @@ async def _push_decision_to_telegram( except Exception as _e: logger.warning("telegram_message_id_db_save_failed", incident_id=incident.incident_id, error=str(_e)) + # Phase 31 (ADR-067 2026-04-10): Log 異常摘要 — NemoTron deepseek-r1:14b + # 非同步執行,不阻塞主流程 + asyncio.create_task(_send_log_summary(incident)) + # 🔴 發送成功後設置去重 key (TTL 10 分鐘) await redis.setex(dedup_key, 600, "1")