Files
ewoooc/docs/adr/ADR-013-aiops-autoheal.md

3.8 KiB
Raw Blame History

ADR-013: AIOps 自動修復閉環架構

狀態: Accepted
日期: 2026-04-19
提案者: Antigravity


背景與問題

EwoooC 系統已有 L1 Hermes 告警派發,但告警只能「通知」,無法「自癒」。 當 psycopg2.OperationalError: could not translate host name "momo-postgres" 這類明確的基礎設施問題發生時,仍需人工 SSH 登入修復,缺乏自動化閉環。


決策

建立三層 AIOps 閉環架構:

Exception → Incident(DB) → PlayBook 匹配 → Auto-Heal 執行 → HealLog(DB) → KM 沉澱(ai_insights) → Telegram 通知

新增元件

元件 類型 說明
database/autoheal_models.py Model Incident / Playbook / HealLog 三張表
migrations/013_autoheal.sql Migration 建表 + 種子 PlayBook 植入
services/auto_heal_service.py Service 核心引擎(分類、匹配、執行、沉澱)
database/manager.py 修改 加入 _init_autoheal_tables()
scheduler.py 修改 三個核心任務植入 handle_exception
requirements.txt 修改 加入 paramiko

PlayBook 動作類型

action_type 說明
DOCKER_RESTART 透過 SSH 跳板 restart 指定容器
SSH_CMD 執行白名單內的任意 SSH 指令
ALERT_ONLY 僅發 Telegram 告警,人工介入
WAIT_RETRY 紀錄後等待排程重試

安全設計

  • SSH 指令白名單:僅允許 docker restart *, docker compose restart *, docker start *
  • 冷卻機制:同 PlayBook 在 cooldown_min 內不重複觸發
  • 升級機制:達到 max_retries 後 incident.status = escalated 並通知人工

KM 沉澱格式

每次修復後寫入 ai_insights

  • insight_type = "auto_heal_playbook"
  • 包含事件、症狀、行動、結果、教訓五要素
  • 自動排入 embedding_retry_queue 完成 RAG 向量化

取捨

優先使用 paramiko 而非 subprocess + CLI ssh原因是在容器內環境控制更精準且支援跳板機 ProxyJump。若 paramiko 未安裝則自動降級到 CLI ssh向後相容


結果

  • P1/P2 等級的 DB_UNREACHABLE / DNS_FAIL 類問題可在 30 秒內完成自動修復
  • 所有修復知識自動沉澱至 RAG KM提升未來 AI 的判斷品質
  • 覆蓋任務:run_auto_import_task / run_icaim_analysis_task / run_weekly_strategy_task

部署後記2026-04-19 實測)

踩坑修正(共 5 個 hotfix commit

問題 原因 修正
UndefinedTable: playbooks 建表順序 [Incident, Playbook, HealLog] FK 衝突 改為 [Playbook, Incident, HealLog]
DetachedInstanceError HealLog/Incident commit() expire_on_commit 後 lazy-load 失敗 session.refresh(obj); session.expunge(obj)
TypeError: NoneType:.0f fallback HealLog 缺 duration_ms except 分支補 duration_ms=duration_ms
compose=True 雙重呼叫 bug _execute_playbook 先呼叫 compose馬上覆寫為 docker restart 刪除 use_compose 分支
No authentication methods available paramiko 找不到 SSH key key 複製至 /app/config/autoheal_id_ed25519rw mount不需重建容器

SSH 認證鏈設定

momo-scheduler → id_ed25519 → 110 (wooo) → tunnel → 188 (ollama) → docker restart

ollama@188id_ed25519.pub 已加入 authorized_keys(第 11 行)。

實測結果

result=success duration=3110ms  # DNS_FAIL → docker restart momo-db 成功

heal_log 在 restart momo-db 後因 DB 瞬斷無法寫入 DBid=7~9 遺失屬設計邊界Telegram 通知仍正常推播。

新增 DB 表

  • migrations/014_telegram_users.sql — EventRouter 推播對象(替代 .env 硬編碼)
    • 種子:telegram_id=-1003940688311, is_admin=true