Files
ewoooc/docs/adr/ADR-013-aiops-autoheal.md
OoO 749eace426
Some checks failed
CD Pipeline / deploy (push) Has been cancelled
移除未使用 Paramiko 依賴
2026-05-13 11:32:04 +08:00

4.7 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
utils/ssh_helper.py Helper 共用 CLI ssh 執行層,供 AutoHeal / AiderHeal 使用

PlayBook 動作類型

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

安全設計

  • SSH 指令白名單2026-04-29 起僅允許明確列入 allowlist 的 read-only 診斷指令;高副作用容器操作需走受控 PlayBook 與保護清單
  • momo-db / momo-postgres 永遠是 protected resource不得被自動 restart / stop / recreate
  • DB / DNS 類離線 playbook 若無法安全修復,降級為 ALERT_ONLYWAIT_RETRY
  • 冷卻機制:同 PlayBook 在 cooldown_min 內不重複觸發
  • 升級機制:達到 max_retries 後 incident.status = escalated 並通知人工

KM 沉澱格式

每次修復後寫入 ai_insights

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

取捨

2026-05-13 實作修訂:現行程式碼已標準化到 utils/ssh_helper.py,以 CLI ssh + ProxyJump 參數組裝執行AutoHeal 與 AiderHeal 共用同一層;因此 paramiko 不再是 runtime 依賴。若未來要重新引入 Paramiko必須同時補回 helper 實作、requirements 與回歸測試。


結果

  • 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 通知仍正常推播。

2026-04-29 安全修訂

上述 DNS_FAIL → docker restart momo-db 屬早期實測紀錄,現在不再允許作為自動修復策略。最新規則:

  • momo-db / momo-postgres 是資料層 protected resource。
  • AutoHeal 寫 DB 失敗時不可讓自癒流程 crash需保留 Telegram / log / fallback 記錄。
  • CODE_FIX、resource action 與 ElephantAlpha orchestration 必須橋接 AutoHeal不得直接執行危險副作用。
  • raw ai_insights 寫入後必須 enqueue embedding讓自癒知識進入 RAG。

新增 DB 表

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