feat(aiops): rule_stats_updater — 計算 noise_rate + true/false positive
All checks were successful
CD Pipeline / build-and-deploy (push) Successful in 8m26s

Review 盲點 5: alert_rule_catalog 68 筆但 noise_rate/TP/FP/last_fired_at 全 NULL

新增 rule_stats_updater_job.py (~170 行):
  每 1h UPDATE 全表 alert_rule_catalog,從 incidents + approval_records 推算:
    - last_fired_at = max(incidents.created_at WHERE alertname=rule_name)
    - true_positive_count = count incidents.status='RESOLVED' past 30d
    - false_positive_count = count approval_records.status='EXPIRED' past 30d
      (EXPIRED = 48h 無人處理,視為假警報 proxy)
    - noise_rate = fp / (tp + fp)

窗口: 30 天 (可配置)
使用單一 UPDATE + subquery,避免 N+1 (68 rule × 3 query = 204 queries → 1 query)

解鎖 E3 Hermes:
  後續 Hermes AI agent 讀 alert_rule_catalog WHERE noise_rate > 0.5
  提案 review_status='deprecated' 或 superseded_by_rule_id

Wire main.py lifespan asyncio.create_task()

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
OG T
2026-04-19 17:05:30 +08:00
parent 505232336b
commit df71c9a37b
2 changed files with 190 additions and 0 deletions

View File

@@ -420,6 +420,16 @@ async def lifespan(_app: FastAPI) -> AsyncGenerator[None, None]:
except Exception as e:
logger.warning("coverage_evaluator_loop_schedule_failed", error=str(e))
# ADR-090 § Rule Stats Updater (2026-04-19 ogt + Claude Opus 4.7 Asia/Taipei)
# 每 1h 從 incidents + approval_records 計算 rule 統計
# 解鎖 E3 Hermes: noise_rate > 0.5 的 rule 可被 AI 提案 deprecate
try:
from src.jobs.rule_stats_updater_job import run_rule_stats_updater_loop
asyncio.create_task(run_rule_stats_updater_loop())
logger.info("rule_stats_updater_loop_scheduled", interval_sec=3600)
except Exception as e:
logger.warning("rule_stats_updater_loop_schedule_failed", error=str(e))
# ADR-076 Task 4: 每日 08:00 台北時間自動日度巡檢報告
# 2026-04-14 Claude Haiku 4.5 Asia/Taipei
try: