feat(GAP-D5 Task 4.2): Postmortem 自動組裝 hook
Some checks failed
CD Pipeline / build-and-deploy (push) Has been cancelled
Some checks failed
CD Pipeline / build-and-deploy (push) Has been cancelled
incident_service.resolve_incident() 結尾 fire-and-forget 呼叫 report_generation_service.trigger_postmortem(),補完孤兒服務的觸發路徑。 觸發條件(由 trigger_postmortem 內部判斷): - duration > POSTMORTEM_MIN_DURATION_MINUTES (10min) - 含 AI root_cause / resolution_action / provider / auto_repaired 背景: - report_generation_service.py 539 行服務於先前 session 建立 - main.py:322 已啟動 run_daily_report_loop(Task 4.1 ✅) - trigger_postmortem 在 src/ 下無呼叫方 → 本 commit 補上 MASTER 藍圖 Phase 4 至此完整收官: ✅ Task 4.1 日度巡檢報告(08:00 台北排程,生產環境已跑) ✅ Task 4.2 Postmortem 自動組裝(本 commit 接上 resolve hook) Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1002,6 +1002,45 @@ class IncidentService:
|
||||
except Exception as _disp_e:
|
||||
logger.warning("disposition_manual_resolve_failed", error=str(_disp_e))
|
||||
|
||||
# MASTER Task 4.2 (2026-04-14 Claude Sonnet 4.6): Postmortem 自動組裝
|
||||
# Incident duration > POSTMORTEM_MIN_DURATION_MINUTES(10min) 時自動生成
|
||||
# 孤兒 report_generation_service.trigger_postmortem 本次接上 resolve 路徑
|
||||
try:
|
||||
import asyncio
|
||||
from src.services.report_generation_service import get_report_generation_service
|
||||
|
||||
alertname = (
|
||||
incident.signals[0].labels.get("alertname", "UnknownAlert")
|
||||
if incident.signals else "UnknownAlert"
|
||||
)
|
||||
title = f"{alertname} — {', '.join(incident.affected_services or ['N/A'])}"
|
||||
root_cause = None
|
||||
resolution_action = None
|
||||
ai_provider = None
|
||||
auto_repaired = False
|
||||
if incident.decision_chain:
|
||||
root_cause = incident.decision_chain.hypothesis
|
||||
ai_provider = incident.decision_chain.model_used
|
||||
if incident.outcome:
|
||||
resolution_action = (incident.outcome.learning_notes or None)
|
||||
auto_repaired = bool(incident.outcome.execution_success)
|
||||
|
||||
asyncio.create_task(
|
||||
get_report_generation_service().trigger_postmortem(
|
||||
incident_id=incident.incident_id,
|
||||
title=title,
|
||||
created_at=incident.signals[0].fired_at if incident.signals else incident.resolved_at,
|
||||
resolved_at=incident.resolved_at,
|
||||
root_cause=root_cause,
|
||||
resolution_action=resolution_action,
|
||||
ai_provider=ai_provider,
|
||||
auto_repaired=auto_repaired,
|
||||
)
|
||||
)
|
||||
except Exception as _pm_e:
|
||||
logger.exception("postmortem_trigger_failed",
|
||||
incident_id=incident_id, error=str(_pm_e))
|
||||
|
||||
return incident
|
||||
|
||||
async def find_by_proposal_id(self, proposal_id: str) -> Incident | None:
|
||||
|
||||
Reference in New Issue
Block a user