Files
awoooi/docs/adr/ADR-064-alert-rule-engine-yaml-driven.md
OG T 428e66c111
Some checks failed
CD Pipeline / build-and-deploy (push) Has been cancelled
fix(arch-review): 首席架構師審查 S1×3 S2×3 S3×3 全修復 + ADR-064
S1 Critical:
- S1-1: asyncio 觸發移至 _call_with_fallback async 上下文,移除 sync 中的 get_event_loop()
- S1-2: _append_rule_to_yaml 加 textwrap.dedent() 正規化 LLM 輸出縮排
- S1-3: _matches() 對 alertname=["*"] 直接回傳 False,防意外命中

S2 Major:
- S2-1: auto_generate_rule() 改為 DI 參數注入 (ollama_url/model/gemini_api_key),移除 import settings
- S2-4: _generate_mock_response docstring 澄清為規則引擎生產路徑,非假數據
- S2-5: suggested_action .strip() 防空白字串繞過 or

S3 Minor:
- S3-2: priority 上界 min(next, 890)
- S3-3: alertname sanitize re.sub([{}]) 防 format KeyError
- S3-4: model_registry.py 最後修改時間戳更新

文件:
- ADR-064: Alert Rule Engine YAML 驅動 + AI 自動學習
- Skills 02: 告警規則引擎 DI 規範 + asyncio 禁止事項
- Skills 03: _generate_mock_response 語意澄清 + 規則引擎降級流程
- LOGBOOK: 本次 Session 完整記錄

2026-04-09 ogt: 首席架構師審查修正

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 10:52:40 +08:00

3.5 KiB
Raw Blame History

ADR-064: Alert Rule Engine — YAML 驅動規則匹配 + AI 自動學習

狀態: 已批准
日期: 2026-04-09
作者: ogt + Claude Sonnet 4.6
審查: 首席架構師2026-04-09


背景

openclaw.py 中的 _generate_mock_response 用硬編碼 if/elif 實作規則匹配,每次新增告警類型都要改 Python 代碼並重新部署。隨著監控目標增加,此模式不可持續。

決策

D1: 規則外化為 YAMLapps/api/alert_rules.yaml

規則引擎從 YAML 檔載入Pod 重啟即生效,不需要改代碼。

規則結構:

rules:
  - id: docker_container_unhealthy
    priority: 10
    match:
      alertname: [DockerContainerUnhealthy]
      message: [unhealthy]
    response:
      kubectl_command: "ssh {host} 'docker inspect {container}...'"
      suggested_action: RESTART_DEPLOYMENT
      risk: medium
      responsibility: INFRA

Priority 體系:

範圍 用途
1499 手寫規則(高優先,不被 AI 覆蓋)
500890 AI 自動生成規則
999 generic_fallback 通用兜底

D2: AI 自動規則學習機制

當告警命中 generic_fallback 時,觸發 auto_generate_rule()

  1. 呼叫 Ollama (deepseek-r1:14b) 生成 YAML 規則片段
  2. Ollama 失敗 → Gemini 2.0 Flash 備援
  3. 驗證格式id/match/response/kubectl_command 必填)
  4. textwrap.dedent() 正規化縮排(防 LLM 輸出前置空格)
  5. append 到 alert_rules.yaml
  6. lru_cache.cache_clear() — 同 Pod 立即生效

D3: 模組邊界

  • alert_rule_engine.py = Service 層,只讀 YAML不直接存取 Redis/DB
  • auto_generate_rule() 採用 DI 參數注入(ollama_url, model, gemini_api_key),不 import settings 全域單例
  • asyncio 觸發在上層 async _call_with_fallback() 執行,不在 sync _generate_mock_response() 中操作 event loop

D4: 匹配邏輯

優先順序alertname 完全匹配 > alert_type 部分匹配 > message 關鍵字

generic_fallbackalertname: ["*"])在 _matches() 中永遠回傳 Falsematch_rule() 的第二輪迴圈單獨選取,防止其 alert_type/message 關鍵字意外命中。

已知限制

L1: 多 Pod 環境下規則可能重複生成

_generating set 是進程記憶體級去重,多 Pod 各自維護。同一告警可能在不同 Pod 同時觸發生成,產生重複規則 append。

緩解: _rule_id_exists() 提供二次去重,但有 lru_cache 的時間窗口 race condition。

計劃: 若未來 Pod 數 > 2需 Redis 分散式鎖。目前 prod 為 2 Pod可接受。

L2: lru_cache 跨 Pod 不同步

新規則寫入後,只有寫入的 Pod 清除了 cache其他 Pod 需重啟才能載入新規則。這是已知行為,下次告警觸發時仍會走 generic_fallback,但不會再次生成(_rule_id_exists 讀 YAML 直接確認)。

測試策略

auto_generate_rule() 採 DI可在不啟動 FastAPI 的情況下單獨測試:

await auto_generate_rule(
    alert_context={"labels": {"alertname": "TestAlert"}},
    ollama_url="http://mock",
    model="test-model",
)

相關檔案

  • apps/api/alert_rules.yaml — 規則定義
  • apps/api/src/services/alert_rule_engine.py — 規則引擎
  • apps/api/src/services/openclaw.py_generate_mock_response + _call_with_fallback 整合點
  • apps/api/Dockerfile — COPY alert_rules.yaml

參考

  • ADR-006: AI 模型路由配置
  • ADR-052: Phase 24 AIRouter
  • feedback_lewooogo_modular_enforcement.md: 積木化 5 問