fix(alerts): correct telegram execution truth
This commit is contained in:
@@ -232,11 +232,32 @@ class ReportGenerationService:
|
||||
async with get_db_context() as db:
|
||||
row = await db.execute(
|
||||
text("""
|
||||
WITH scoped AS (
|
||||
SELECT
|
||||
*,
|
||||
(
|
||||
COALESCE(extra_metadata->>'execution_kind', '') = 'no_action'
|
||||
OR COALESCE(extra_metadata->>'repair_executed', '') = 'false'
|
||||
OR btrim(coalesce(action, '')) = ''
|
||||
OR UPPER(action) LIKE 'OBSERVE%'
|
||||
OR UPPER(action) LIKE 'INVESTIGATE%'
|
||||
OR UPPER(action) LIKE 'NO_ACTION%'
|
||||
OR UPPER(action) LIKE '% NO_ACTION%'
|
||||
OR UPPER(action) LIKE '%| NO_ACTION%'
|
||||
) AS is_observe_only
|
||||
FROM approval_records
|
||||
WHERE created_at >= :since
|
||||
)
|
||||
SELECT
|
||||
COUNT(*) FILTER (WHERE UPPER(status::text) = 'EXECUTION_SUCCESS') AS success,
|
||||
COUNT(*) FILTER (WHERE UPPER(status::text) = 'EXECUTION_FAILED') AS failed
|
||||
FROM approval_records
|
||||
WHERE created_at >= :since
|
||||
COUNT(*) FILTER (
|
||||
WHERE UPPER(status::text) = 'EXECUTION_SUCCESS'
|
||||
AND NOT is_observe_only
|
||||
) AS success,
|
||||
COUNT(*) FILTER (
|
||||
WHERE UPPER(status::text) = 'EXECUTION_FAILED'
|
||||
AND NOT is_observe_only
|
||||
) AS failed
|
||||
FROM scoped
|
||||
"""),
|
||||
{"since": since},
|
||||
)
|
||||
@@ -460,6 +481,7 @@ class ReportGenerationService:
|
||||
# 失敗時發送告警到 SRE 群組,避免靜默吞掉錯誤
|
||||
import asyncio as _asyncio
|
||||
report_text = self.format_postmortem(data)
|
||||
await self._persist_postmortem_km(data, report_text)
|
||||
from src.services.telegram_gateway import get_telegram_gateway
|
||||
gateway = get_telegram_gateway()
|
||||
|
||||
@@ -510,6 +532,72 @@ class ReportGenerationService:
|
||||
error=str(_fe),
|
||||
)
|
||||
|
||||
async def _persist_postmortem_km(
|
||||
self,
|
||||
data: PostmortemData,
|
||||
report_text: str,
|
||||
) -> None:
|
||||
"""Persist generated postmortem as an idempotent KM entry before Telegram send."""
|
||||
try:
|
||||
from src.db.base import get_db_context
|
||||
from src.models.knowledge import (
|
||||
EntrySource,
|
||||
EntryStatus,
|
||||
EntryType,
|
||||
KnowledgeEntryCreate,
|
||||
)
|
||||
from src.repositories.alert_operation_log_repository import (
|
||||
get_alert_operation_log_repository,
|
||||
)
|
||||
from src.repositories.knowledge_repository import KnowledgeDBRepository
|
||||
|
||||
async with get_db_context() as db:
|
||||
repo = KnowledgeDBRepository(db)
|
||||
entry = await repo.create(
|
||||
KnowledgeEntryCreate(
|
||||
title=f"Postmortem {data.incident_id}: {data.title}"[:255],
|
||||
content=report_text,
|
||||
entry_type=EntryType.POSTMORTEM,
|
||||
category="postmortem",
|
||||
tags=[
|
||||
"postmortem",
|
||||
"incident",
|
||||
"telegram",
|
||||
"auto_repaired" if data.auto_repaired else "human_intervention",
|
||||
],
|
||||
source=EntrySource.AI_EXTRACTED,
|
||||
status=EntryStatus.REVIEW,
|
||||
related_incident_id=data.incident_id,
|
||||
path_type="postmortem",
|
||||
created_by="report_generation_service",
|
||||
)
|
||||
)
|
||||
|
||||
await get_alert_operation_log_repository().append(
|
||||
"KM_CONVERTED",
|
||||
incident_id=data.incident_id,
|
||||
actor="report_generation_service",
|
||||
action_detail="postmortem_persisted",
|
||||
success=True,
|
||||
context={
|
||||
"knowledge_entry_id": entry.id,
|
||||
"entry_type": EntryType.POSTMORTEM.value,
|
||||
"path_type": "postmortem",
|
||||
"duration_minutes": round(data.duration_minutes, 2),
|
||||
},
|
||||
)
|
||||
logger.info(
|
||||
"postmortem_km_persisted",
|
||||
incident_id=data.incident_id,
|
||||
knowledge_entry_id=entry.id,
|
||||
)
|
||||
except Exception as e:
|
||||
logger.warning(
|
||||
"postmortem_km_persist_failed",
|
||||
incident_id=data.incident_id,
|
||||
error=str(e),
|
||||
)
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# 日度報告排程迴圈
|
||||
|
||||
Reference in New Issue
Block a user