- 異常頻率追蹤架構 (Redis 計數器 + 滑動窗口) - 修復策略分級 (Tier 1-4: 重啟→緩解→根因→架構) - AI 學習服務 (LearningService + Playbook 自動更新) - Telegram 頻率告警格式 (重複次數 + 成功率統計) - 實作清單 (P0: 22h, P1: 12h, P2: 8h) 🔴 關鍵觀點: 重啟只是治標,不是治本 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
55 KiB
55 KiB
AWOOOI 監控戰略規劃 - 全面性討論
版本: v1.0 DRAFT 建立日期: 2026-03-29 狀態: 待統帥審核 目標: 從問題發生到解決的全閉環、角色分層、零遺漏
一、核心原則定錨
┌─────────────────────────────────────────────────────────────────────┐
│ 監控金三角 (必須同時達成) │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 即時性 ←──────────────────→ 完整性 │
│ ↑ ↑ │
│ │ │ │
│ │ 監控 │ │
│ │ │ │
│ └───────────┬───────────────┘ │
│ ↓ │
│ 可行動性 │
│ │
│ 即時性: 發生 → 告警 < 30 秒 │
│ 完整性: 從觸發到解決的完整時間軸 │
│ 可行動性: 每個告警都有明確的 Next Action │
│ │
└─────────────────────────────────────────────────────────────────────┘
1.1 監控閉環時序目標
| 階段 | 目標時效 | 說明 |
|---|---|---|
| T0: 異常發生 | 0s | 系統出現異常狀態 |
| T1: 偵測 | < 15s | Prometheus/Sentry/SignOz 捕獲 |
| T2: 告警觸發 | < 30s | Alertmanager 發送到 AWOOOI |
| T3: AI 分析 | < 60s | OpenClaw 完成根因分析 |
| T4: 通知到人 | < 90s | Telegram 推送 (含建議方案) |
| T5: 決策 | < 5min | 人工審核或自動執行 |
| T6: 執行 | < 1min | K8s Executor 執行修復 |
| T7: 驗證 | < 2min | 健康檢查確認修復成功 |
| T8: 報告 | 即時 | 完整時間軸報告生成 |
總目標: 從異常到修復 < 10 分鐘 (P0 Critical)
二、現有產品/架構/規範全面清查
2.1 已實作清單 (截至 2026-03-29)
| 類別 | 項目 | 實作狀態 | 即時性 | 完整性 | 可行動性 |
|---|---|---|---|---|---|
| 基礎設施 | K8s Pod 健康 | ✅ Prometheus | ✅ | ✅ | ⚠️ 需 OpenClaw |
| Node 資源 | ✅ node-exporter | ✅ | ✅ | ⚠️ | |
| etcd 狀態 | ✅ K3s 內建 | ✅ | ⚠️ | ❌ | |
| 應用層 | API 錯誤率 | ✅ Sentry | ✅ | ✅ | ✅ |
| API 延遲 | ✅ SignOz | ✅ | ✅ | ⚠️ | |
| 前端錯誤 | ✅ Sentry | ✅ | ⚠️ | ⚠️ | |
| 資料層 | PostgreSQL | ⚠️ 部分 | ⚠️ | ❌ | ❌ |
| Redis | ⚠️ 部分 | ⚠️ | ❌ | ❌ | |
| AI/LLM | Ollama | ⚠️ 健康檢查 | ⚠️ | ❌ | ❌ |
| Token 成本 | ✅ Langfuse | ✅ | ✅ | ⚠️ | |
| CI/CD | GitHub Runner | ⚠️ healthcheck | ⚠️ | ❌ | ❌ |
| Harbor | ⚠️ | ⚠️ | ❌ | ❌ | |
| 告警通道 | Telegram 推送 | ✅ | ✅ | ✅ | ✅ |
| Telegram 按鈕 | ✅ 剛修復 | ✅ | ✅ | ✅ | |
| AI 分析 | OpenClaw | ✅ | ✅ | ✅ | ✅ |
| 自動修復 | K8s Executor | ✅ 部分動作 | ✅ | ⚠️ | ⚠️ |
| 報告 | 時間軸 | ❌ 缺失 | ❌ | ❌ | ❌ |
2.2 關鍵缺口分析
┌─────────────────────────────────────────────────────────────────────┐
│ 缺口優先級矩陣 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ 影響 │
│ ↑ │
│ │ ┌─────────────┐ │
│ 高 │ │ P0 區域 │ • 靜默失敗 (try/except 吞錯誤) │
│ │ │ 立即修復 │ • 時間軸報告缺失 │
│ │ └─────────────┘ • 資料庫監控不足 │
│ │ │
│ 中 │ ┌─────────────┐ │
│ │ │ P1 區域 │ • SignOz 告警規則 │
│ │ │ 本週內 │ • 自動修復動作擴展 │
│ │ └─────────────┘ • CI/CD 監控 │
│ │ │
│ 低 │ ┌─────────────┐ │
│ │ │ P2 區域 │ • Grafana 儀表板 │
│ │ │ 後續迭代 │ • SLO/SLI 定義 │
│ │ └─────────────┘ • 容量預測 │
│ │ │
│ └──────────────────────────────────────────────────────────────→ │
│ 低 中 高 頻率 │
│ │
└─────────────────────────────────────────────────────────────────────┘
三、角色分層架構 (Role-Based Views)
3.1 為什麼需要分層?
現有的「全局戰情室」設計目標是 運維人員 (SRE/DevOps):
- 顯示所有技術細節
- kubectl 指令、Pod 狀態、Trace ID
- 需要技術背景才能理解
但實際使用者包含多種角色:
| 角色 | 關注點 | 需要的資訊 | 不需要的資訊 |
|---|---|---|---|
| CEO | 業務影響 | 收入損失、用戶影響、SLA 達標率 | kubectl 指令、Pod 名稱 |
| CTO | 技術決策 | 架構風險、技術債、系統健康度 | 單一 Pod 細節 |
| CIO | 整體營運 | 成本、效率、資源使用率 | 代碼層級錯誤 |
| CISO | 安全事件 | 安全告警、異常存取、合規狀態 | 效能指標 |
| Team Lead | 團隊負責範圍 | 自己團隊的服務狀態 | 其他團隊細節 |
| On-Call | 即時處理 | 所有告警、處理建議、執行按鈕 | 歷史趨勢 |
| 開發者 | 自己的代碼 | 錯誤堆疊、相關 Commit | 基礎設施狀態 |
3.2 分層架構設計
┌─────────────────────────────────────────────────────────────────────┐
│ AWOOOI 監控分層架構 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Layer 0: Executive Dashboard │ │
│ │ (CEO/CTO/CIO/CISO) │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │ 系統 │ │ 本月 │ │ SLA │ │ 安全 │ │ │
│ │ │ 健康度 │ │ 成本 │ │ 達標率 │ │ 事件數 │ │ │
│ │ │ 98.5% │ │ $1,234 │ │ 99.9% │ │ 0 │ │ │
│ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ │
│ │ │ │
│ │ 🟢 正常運作中 | 最近事件: 2 小時前 (已自動修復) │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ ↓ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Layer 1: Ops Center │ │
│ │ (Team Lead / Manager) │ │
│ │ │ │
│ │ ┌──────────────────────────────────────────────────────┐ │ │
│ │ │ 團隊: Backend │ │ │
│ │ │ ├─ awoooi-api: 🟢 Healthy (2/2 pods) │ │ │
│ │ │ ├─ awoooi-worker: 🟢 Healthy (1/1 pods) │ │ │
│ │ │ └─ 本週事件: 3 (已解決: 3) │ │ │
│ │ └──────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ ┌──────────────────────────────────────────────────────┐ │ │
│ │ │ 團隊: Frontend │ │ │
│ │ │ ├─ awoooi-web: 🟢 Healthy (2/2 pods) │ │ │
│ │ │ └─ 本週事件: 1 (已解決: 1) │ │ │
│ │ └──────────────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ ↓ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Layer 2: War Room (現有全局戰情室) │ │
│ │ (On-Call / SRE / DevOps) │ │
│ │ │ │
│ │ 完整技術細節: │ │
│ │ - 即時告警清單 │ │
│ │ - AI 分析結果 │ │
│ │ - kubectl 指令 │ │
│ │ - 簽核按鈕 (Y/n) │ │
│ │ - Timeline 時間軸 │ │
│ │ - SignOz Trace 連結 │ │
│ │ - Sentry Issue 連結 │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ ↓ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Layer 3: Developer Console │ │
│ │ (開發者) │ │
│ │ │ │
│ │ - 自己負責服務的錯誤 │ │
│ │ - Stack Trace │ │
│ │ - 相關 Commit / PR │ │
│ │ - 修復建議 │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
3.3 路徑規劃
| 階段 | 內容 | 優先級 |
|---|---|---|
| 現在 | Layer 2 (War Room) - 已存在的全局戰情室 | ✅ 已有 |
| Phase 1 | Layer 0 (Executive) - C-Level 儀表板 | P2 |
| Phase 2 | Layer 1 (Ops Center) - 團隊視圖 | P2 |
| Phase 3 | Layer 3 (Developer) - 開發者控制台 | P3 |
首席架構師建議: Layer 2 (War Room) 是核心,優先強化監控能力。Layer 0/1/3 可後續迭代。
四、監控深度定義
4.1 監控層級標準
┌─────────────────────────────────────────────────────────────────────┐
│ 監控深度金字塔 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ┌───────┐ │
│ / L4 \ │
│ / 預測 \ │
│ / (未來) \ │
│ ├─────────────┤ │
│ / L3 \ │
│ / 根因分析 \ │
│ / (為什麼發生) \ │
│ ├───────────────────┤ │
│ / L2 \ │
│ / 上下文追蹤 \ │
│ / (影響範圍/關聯) \ │
│ ├─────────────────────────┤ │
│ / L1 \ │
│ / 即時告警 \ │
│ / (發生了什麼) \ │
│ ├───────────────────────────────┤ │
│ / L0 \ │
│ / 健康檢查 \ │
│ / (還活著嗎) \ │
│ └───────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
4.2 各層級實作標準
| 層級 | 定義 | 實作要求 | 當前狀態 |
|---|---|---|---|
| L0: 健康檢查 | 服務是否存活 | 每個服務必須有 health endpoint | ✅ 90% |
| L1: 即時告警 | 發生了什麼異常 | 每個異常必須觸發告警 | ⚠️ 70% |
| L2: 上下文追蹤 | 影響範圍、關聯服務 | 每個告警必須有 Trace Context | ⚠️ 60% |
| L3: 根因分析 | 為什麼發生 | AI 分析每個 P0/P1 告警 | ✅ 80% |
| L4: 預測 | 可能會發生什麼 | ML 模型預測資源瓶頸 | ❌ 0% |
4.3 各服務監控深度目標
| 服務類型 | L0 | L1 | L2 | L3 | L4 | 備註 |
|---|---|---|---|---|---|---|
| P0 Critical (API, DB, Redis) | ✅ 必須 | ✅ 必須 | ✅ 必須 | ✅ 必須 | 🟡 建議 | 核心服務全覆蓋 |
| P1 High (Worker, Ollama, OpenClaw) | ✅ 必須 | ✅ 必須 | ✅ 必須 | 🟡 建議 | ❌ 可選 | 關鍵 AI 服務 |
| P2 Medium (SignOz, Langfuse, Harbor) | ✅ 必須 | ✅ 必須 | 🟡 建議 | ❌ 可選 | ❌ 可選 | 可觀測性工具 |
| P3 Low (Grafana, ArgoCD UI) | ✅ 必須 | 🟡 建議 | ❌ 可選 | ❌ 可選 | ❌ 可選 | 輔助工具 |
五、完整事件生命週期 (Incident Lifecycle)
5.1 事件狀態機
┌─────────────────────────────────────────────────────────────────────┐
│ 事件生命週期狀態機 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────┐ │
│ │ CREATED │ ← 異常偵測 │
│ └────┬─────┘ │
│ │ AI 分析完成 │
│ ▼ │
│ ┌──────────┐ │
│ │ ANALYZED │ ← OpenClaw 完成分析 │
│ └────┬─────┘ │
│ │ │
│ ┌────┴────┐ │
│ │ │ │
│ ▼ ▼ │
│ ┌─────────────┐ ┌──────────────┐ │
│ │ AUTO_REPAIR │ │ AWAITING_ │ ← 需人工審核 │
│ │ (自動修復) │ │ APPROVAL │ │
│ └──────┬──────┘ └───────┬──────┘ │
│ │ │ │
│ │ ┌───────┴───────┐ │
│ │ │ │ │
│ │ ▼ ▼ │
│ │ ┌─────────┐ ┌──────────┐ │
│ │ │ APPROVED│ │ REJECTED │ │
│ │ └────┬────┘ └────┬─────┘ │
│ │ │ │ │
│ └────┬────┘ │ │
│ │ │ │
│ ▼ │ │
│ ┌─────────┐ │ │
│ │EXECUTING│ ← K8s Executor 執行中 │
│ └────┬────┘ │ │
│ │ │ │
│ ┌────┴────┐ │ │
│ │ │ │ │
│ ▼ ▼ │ │
│ ┌─────────┐ ┌─────────┐ │ │
│ │ SUCCESS │ │ FAILED │ │ │
│ └────┬────┘ └────┬────┘ │ │
│ │ │ │ │
│ └─────┬──────┴──────────┘ │
│ │ │
│ ▼ │
│ ┌──────────┐ │
│ │ RESOLVED │ ← 最終狀態 (保留歷史記錄) │
│ └──────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
5.2 事件時間軸報告 (缺失的關鍵功能)
═══════════════════════════════════════════════════════════════
📋 事件報告: INC-20260329-0001
═══════════════════════════════════════════════════════════════
🔴 嚴重度: CRITICAL
🎯 影響服務: awoooi-api
👥 責任團隊: Backend
📊 處理時效: 3 分 42 秒 (SLA 目標: 10 分鐘 ✅)
───────────────────────────────────────────────────────────────
📅 時間軸
───────────────────────────────────────────────────────────────
09:15:00 🔴 [偵測] Prometheus 告警觸發
│ • alertname: PodCrashLoopBackOff
│ • pod: awoooi-api-7d4b8c9f5-abc12
│ • namespace: awoooi-prod
│
09:15:12 📡 [接收] AWOOOI Webhook 收到告警
│ • fingerprint: a1b2c3d4
│ • 去重檢查: 通過 (新告警)
│
09:15:18 🧠 [分析] OpenClaw AI 開始分析
│ • 收集 K8s Events
│ • 查詢 Pod Logs (最後 100 行)
│ • 比對歷史 Playbook
│
09:15:42 ✅ [完成] OpenClaw 分析完成
│ • 根因: OOM Killed (Memory exceeded)
│ • 建議: DELETE_POD + SCALE_UP
│ • 信心度: 92%
│ • 風險等級: LOW
│ • Tokens: 1,234 / $0.0012
│
09:15:45 📱 [通知] Telegram 推送完成
│ • Chat ID: -1001234567890
│ • Message ID: 12345
│
09:16:02 ✅ [核准] 統帥點擊 [✅ 簽核]
│ • 審核者: @owenhytsai
│ • 決策時間: 17 秒
│
09:16:05 🔧 [執行] K8s Executor 開始
│ • Command: kubectl delete pod awoooi-api-7d4b8c9f5-abc12
│
09:16:08 ✅ [成功] Pod 刪除成功
│ • 新 Pod 啟動中...
│
09:16:35 🔧 [執行] 擴展副本數
│ • Command: kubectl scale deployment/awoooi-api --replicas=3
│
09:16:38 ✅ [成功] 擴展完成
│
09:17:20 ✅ [驗證] 健康檢查通過
│ • /api/v1/health: 200 OK
│ • 所有 Pod: Running
│
09:18:42 📊 [結案] 事件標記為 RESOLVED
│ • 總處理時間: 3 分 42 秒
│ • 自動化程度: 85%
│ • 人工介入: 核准 (17 秒)
───────────────────────────────────────────────────────────────
📈 指標
───────────────────────────────────────────────────────────────
• MTTR (修復時間): 3 分 42 秒
• MTTA (確認時間): 45 秒
• 影響時間: 約 4 分鐘
• 影響用戶: 估計 50-100 人
───────────────────────────────────────────────────────────────
🔗 相關連結
───────────────────────────────────────────────────────────────
• SignOz Trace: http://192.168.0.188:3301/trace/abc123
• Sentry Issue: (無相關)
• Langfuse: http://192.168.0.110:3100/traces/xyz789
• Approval: http://awoooi.wooo.tw/authorizations/INC-20260329-0001
───────────────────────────────────────────────────────────────
💡 改進建議 (AI 生成)
───────────────────────────────────────────────────────────────
1. 建議增加 memory limit 從 512Mi 到 768Mi
2. 建議設置 HPA (Horizontal Pod Autoscaler)
3. 考慮 Playbook 自動化 (信心度 > 95% 時)
═══════════════════════════════════════════════════════════════
六、監控項目完整清單
6.1 服務健康 (L0)
| 項目 | 監控方式 | 當前狀態 | 目標狀態 |
|---|---|---|---|
| awoooi-api | HTTP /api/v1/health | ✅ | ✅ |
| awoooi-web | HTTP / | ✅ | ✅ |
| awoooi-worker | Exec mtime | ✅ | ✅ |
| ollama | HTTP /api/tags | ✅ | ✅ |
| openclaw | HTTP /health | ✅ | ✅ |
| postgres | pg_isready | ⚠️ Docker 內部 | ✅ Prometheus Exporter |
| redis | redis-cli ping | ⚠️ Docker 內部 | ✅ Redis Exporter |
| harbor | HTTP /api/v2.0/health | ⚠️ | ✅ |
| sentry | HTTP /_health/ | ⚠️ | ✅ |
| langfuse | HTTP /api/public/health | ⚠️ | ✅ |
| github-runner | systemctl status | ⚠️ | ✅ |
| signoz | HTTP / (UI) | ✅ | ✅ |
| clickhouse | HTTP /ping | ⚠️ | ✅ |
6.2 即時告警 (L1)
| 告警類型 | 當前狀態 | 目標狀態 | 優先級 |
|---|---|---|---|
| 應用錯誤 | |||
| Sentry Exception → Telegram | ⚠️ 有 Webhook,但無 Telegram | ✅ 直接推送 | P0 |
| HTTP 5xx 激增 | ✅ Prometheus | ✅ | - |
| API 延遲 P95 > 2s | ⚠️ SignOz 有數據 | ✅ 告警規則 | P1 |
| 基礎設施 | |||
| Pod CrashLoop | ✅ Prometheus | ✅ | - |
| Node NotReady | ✅ Prometheus | ✅ | - |
| Disk > 85% | ✅ Prometheus | ✅ | - |
| 資料庫 | |||
| PostgreSQL Down | ⚠️ 無 | ✅ pg_exporter | P0 |
| PostgreSQL 連線池 > 80% | ⚠️ 無 | ✅ pg_exporter | P1 |
| Redis Memory > 80% | ⚠️ 無 | ✅ redis_exporter | P1 |
| AI/LLM | |||
| Ollama Timeout > 60s | ⚠️ 無 | ✅ 自訂 Metrics | P1 |
| Gemini Rate Limit | ✅ Rate Limiter | ✅ | - |
| Token 成本超標 | ⚠️ Langfuse 有數據 | ✅ 告警規則 | P2 |
| CI/CD | |||
| Runner Offline | ⚠️ healthcheck | ✅ Prometheus | P0 |
| Workflow Failed | ⚠️ 無 | ✅ GitHub Webhook | P1 |
6.3 上下文追蹤 (L2)
| 追蹤項目 | 當前狀態 | 目標狀態 | 說明 |
|---|---|---|---|
| Request Trace | ✅ SignOz | ✅ | 完整 Span 追蹤 |
| Error → Trace 連結 | ✅ Sentry | ✅ | Deep Linking |
| 告警 → 相關服務 | ⚠️ 部分 | ✅ blast_radius | 需強化 |
| 告警 → 歷史比對 | ❌ | ✅ | Playbook 匹配 |
| DB Query Trace | ⚠️ 部分 | ✅ | SQLAlchemy 埋點 |
| Redis Command Trace | ❌ | ✅ | redis-py 埋點 |
6.4 根因分析 (L3)
| 分析項目 | 當前狀態 | 目標狀態 | 說明 |
|---|---|---|---|
| Alertmanager → OpenClaw | ✅ | ✅ | 已實作 |
| Sentry → OpenClaw | ✅ | ✅ | 已實作 |
| SignOz 異常 → OpenClaw | ❌ | ✅ | 需實作 ClickHouse 查詢 |
| 責任團隊判定 | ✅ | ✅ | AI 仲裁 |
| 修復建議生成 | ✅ | ✅ | kubectl 指令 |
6.5 預測 (L4) - 未來
| 預測項目 | 當前狀態 | 目標狀態 | 說明 |
|---|---|---|---|
| 資源瓶頸預測 | ❌ | 🟡 Phase 3 | ML 模型 |
| 告警趨勢預測 | ❌ | 🟡 Phase 3 | 時序分析 |
| 成本預測 | ❌ | 🟡 Phase 3 | Token 使用趨勢 |
七、與全局戰情室的關係
7.1 決策:整合 vs 分離
| 方案 | 優點 | 缺點 | 建議 |
|---|---|---|---|
| 整合 (在現有戰情室擴展) | 單一入口、用戶熟悉 | 可能變得臃腫 | ✅ 推薦 |
| 分離 (獨立監控中心) | 清晰分工 | 維護成本高、用戶需切換 | ❌ |
首席架構師建議: 整合方案
理由:
- 現有戰情室已有完整基礎 (Approval、Incident、Timeline)
- 監控與處理應該在同一畫面 (減少上下文切換)
- 透過 Tab/Section 區分不同資訊層級
7.2 整合方案設計
┌─────────────────────────────────────────────────────────────────────┐
│ 全局戰情室 v2.0 (整合監控) │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Header │ │
│ │ ┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐ │ │
│ │ │ 概覽 │ │ 告警 │ │ 服務 │ │ 追蹤 │ │ 報告 │ │ │
│ │ └───────┘ └───────┘ └───────┘ └───────┘ └───────┘ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────┐ ┌──────────────────────────────────┐ │
│ │ 左側: 服務健康地圖 │ │ 右側: 事件/告警/追蹤 │ │
│ │ │ │ │ │
│ │ 🟢 awoooi-api (2/2) │ │ Tab: [即時告警] [待處理] [歷史] │ │
│ │ 🟢 awoooi-web (2/2) │ │ │ │
│ │ 🟢 awoooi-worker (1/1)│ │ ┌────────────────────────────┐ │ │
│ │ 🟢 ollama (健康) │ │ │ 🔴 CRITICAL | awoooi-api │ │ │
│ │ 🟢 postgres (健康) │ │ │ 09:15:00 | PodCrashLoop │ │ │
│ │ 🟢 redis (健康) │ │ │ [查看詳情] [AI 分析中...] │ │ │
│ │ │ │ └────────────────────────────┘ │ │
│ │ ───────────────── │ │ │ │
│ │ 系統指標 │ │ ┌────────────────────────────┐ │ │
│ │ CPU: 45% ███████░░░ │ │ │ 🟡 WARNING | postgres │ │ │
│ │ MEM: 62% █████████░ │ │ │ 09:10:00 | ConnectionPool │ │ │
│ │ Disk: 55% ████████░░ │ │ │ [查看詳情] [已自動處理] │ │ │
│ │ │ │ └────────────────────────────┘ │ │
│ └────────────────────────┘ └──────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 底部: 事件時間軸 (Timeline) │ │
│ │ ────────●─────────●──────────●────────●─────────●─────────→ │ │
│ │ 09:15 09:16 09:17 09:18 09:19 │ │
│ │ 偵測 分析 核准 執行 修復 │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
八、實作路線圖
Phase 0: 立即修復 (今天)
| 項目 | 狀態 | 說明 |
|---|---|---|
| Telegram 按鈕修復 | ✅ 已完成 | b0b91a5 |
| Sentry OpenClaw URL | ✅ 已完成 | d6dc80b |
| 驗證按鈕功能 | ⬜ 待測試 | 觸發測試告警 |
Phase 1: 消滅靜默失敗 (本週)
| 項目 | 工時 | 說明 |
|---|---|---|
| 所有 try/except 加 Sentry | 2h | 代碼審查 + 修改 |
| Sentry Issue → Telegram 即時推送 | 1h | 已有 Webhook,補 Telegram |
| 事件時間軸報告 | 4h | 新功能開發 |
| 資料庫監控 (pg_exporter, redis_exporter) | 2h | Docker 部署 |
Phase 2: 完善告警 (下週)
| 項目 | 工時 | 說明 |
|---|---|---|
| SignOz 告警規則 | 2h | Error Rate, Latency |
| 自動修復動作擴展 | 4h | SCALE_UP, ROLLBACK |
| Playbook 萃取 | 4h | 成功修復 → 自動記錄 |
| CI/CD 監控 | 2h | GitHub Webhook |
Phase 3: 角色分層 (兩週後)
| 項目 | 工時 | 說明 |
|---|---|---|
| Executive Dashboard (L0) | 8h | C-Level 視圖 |
| Ops Center (L1) | 6h | 團隊視圖 |
| Grafana 儀表板 | 4h | 視覺化 |
九、異常頻率統計與根本修復 (2026-03-29 統帥新增)
關鍵觀點: 重啟只是治標,不是治本!太常發生的異常必須徹底解決
9.1 異常頻率追蹤架構
┌─────────────────────────────────────────────────────────────────────┐
│ 異常頻率追蹤閉環 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ 異常發生 │────▶│ 計數統計 │────▶│ 模式識別 │────▶│ 根因修復 │ │
│ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │
│ │ │ │ │ │
│ │ ▼ ▼ ▼ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ │ Redis │ │ OpenClaw│ │ Playbook│ │
│ │ │ 計數器 │ │ 模式分析 │ │ 自動生成│ │
│ │ └─────────┘ └─────────┘ └─────────┘ │
│ │ │ │ │ │
│ │ └────────────────┴──────────────┘ │
│ │ │ │
│ │ ▼ │
│ │ ┌──────────────────┐ │
│ │ │ 閾值觸發告警 │ │
│ │ │ (同一問題 > 3次) │ │
│ │ └──────────────────┘ │
│ │ │ │
│ │ ▼ │
│ │ ┌──────────────────┐ │
│ └───────────────────▶│ Telegram 特別通知 │ │
│ 第 1 次 = 普通告警 │ 「此問題本月第 N 次」│ │
│ 第 3 次 = 重複告警 └──────────────────┘ │
│ 第 5 次 = 升級告警 │
│ │
└─────────────────────────────────────────────────────────────────────┘
9.2 計數器設計
# apps/api/src/services/anomaly_counter.py
"""
異常頻率統計服務
"""
from datetime import datetime, timedelta
from typing import NamedTuple
import redis
import structlog
logger = structlog.get_logger(__name__)
class AnomalyFrequency(NamedTuple):
"""異常頻率資料"""
anomaly_key: str # 異常唯一識別 (hash of error signature)
count_1h: int # 1 小時內發生次數
count_24h: int # 24 小時內發生次數
count_7d: int # 7 天內發生次數
count_30d: int # 30 天內發生次數
first_seen: datetime # 首次發生時間
last_seen: datetime # 最近發生時間
auto_repair_count: int # 自動修復嘗試次數
permanent_fix_applied: bool # 是否已套用永久修復
class AnomalyCounter:
"""
異常計數器 - 追蹤每種異常的發生頻率
使用 Redis Sorted Set 實作滑動窗口計數
"""
THRESHOLDS = {
'REPEAT_ALERT': 3, # 3 次重複 → 升級告警
'ESCALATE': 5, # 5 次重複 → 人工介入
'PERMANENT_FIX': 10, # 10 次重複 → 必須永久修復
}
def __init__(self, redis_client: redis.Redis):
self.redis = redis_client
def record_anomaly(self, anomaly_signature: dict) -> AnomalyFrequency:
"""
記錄一次異常發生
Args:
anomaly_signature: 異常簽名 (包含 error_type, service, culprit 等)
Returns:
AnomalyFrequency: 當前頻率統計
"""
# 生成唯一 key (基於異常簽名的 hash)
anomaly_key = self._hash_signature(anomaly_signature)
now = datetime.now()
timestamp = now.timestamp()
# 添加到 Sorted Set (score = timestamp)
self.redis.zadd(f"anomaly:timeline:{anomaly_key}", {str(timestamp): timestamp})
# 清理過期數據 (30 天前)
cutoff_30d = (now - timedelta(days=30)).timestamp()
self.redis.zremrangebyscore(f"anomaly:timeline:{anomaly_key}", '-inf', cutoff_30d)
# 計算各時間窗口的計數
count_1h = self.redis.zcount(
f"anomaly:timeline:{anomaly_key}",
(now - timedelta(hours=1)).timestamp(),
'+inf'
)
count_24h = self.redis.zcount(
f"anomaly:timeline:{anomaly_key}",
(now - timedelta(hours=24)).timestamp(),
'+inf'
)
count_7d = self.redis.zcount(
f"anomaly:timeline:{anomaly_key}",
(now - timedelta(days=7)).timestamp(),
'+inf'
)
count_30d = self.redis.zcount(
f"anomaly:timeline:{anomaly_key}",
cutoff_30d,
'+inf'
)
# 取得首次/最近時間
first_seen_ts = self.redis.zrange(f"anomaly:timeline:{anomaly_key}", 0, 0, withscores=True)
last_seen_ts = self.redis.zrange(f"anomaly:timeline:{anomaly_key}", -1, -1, withscores=True)
# 自動修復次數
auto_repair_count = int(self.redis.get(f"anomaly:repair_count:{anomaly_key}") or 0)
permanent_fix = self.redis.get(f"anomaly:permanent_fix:{anomaly_key}") == b'1'
freq = AnomalyFrequency(
anomaly_key=anomaly_key,
count_1h=count_1h,
count_24h=count_24h,
count_7d=count_7d,
count_30d=count_30d,
first_seen=datetime.fromtimestamp(first_seen_ts[0][1]) if first_seen_ts else now,
last_seen=datetime.fromtimestamp(last_seen_ts[0][1]) if last_seen_ts else now,
auto_repair_count=auto_repair_count,
permanent_fix_applied=permanent_fix,
)
# 記錄日誌
logger.info(
"anomaly_recorded",
anomaly_key=anomaly_key,
count_24h=count_24h,
count_30d=count_30d,
)
return freq
def should_escalate(self, freq: AnomalyFrequency) -> str | None:
"""
判斷是否需要升級處理
Returns:
None: 不需要升級
'REPEAT': 重複告警 (3-4 次)
'ESCALATE': 人工介入 (5-9 次)
'PERMANENT_FIX': 必須永久修復 (10+ 次)
"""
if freq.count_24h >= self.THRESHOLDS['PERMANENT_FIX']:
return 'PERMANENT_FIX'
elif freq.count_24h >= self.THRESHOLDS['ESCALATE']:
return 'ESCALATE'
elif freq.count_24h >= self.THRESHOLDS['REPEAT_ALERT']:
return 'REPEAT'
return None
9.3 根本修復 vs 重啟
┌─────────────────────────────────────────────────────────────────────┐
│ 修復策略分級 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 🔴 Tier 1: 臨時修復 (重啟類) │ │
│ │ 適用: 首次發生、原因不明 │ │
│ │ 動作: restart_pod, restart_container │ │
│ │ 限制: 同一問題最多用 2 次 │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ ↓ 重複發生 │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 🟡 Tier 2: 緩解修復 (資源調整類) │ │
│ │ 適用: 資源不足、負載問題 │ │
│ │ 動作: scale_up, increase_memory, adjust_limits │ │
│ │ 條件: 已重啟 2 次仍未解決 │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ ↓ 繼續發生 │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 🟢 Tier 3: 根本修復 (代碼/配置修復) │ │
│ │ 適用: 已識別根因 │ │
│ │ 動作: apply_hotfix, update_config, patch_deployment │ │
│ │ 要求: OpenClaw AI 分析 + 人工確認 │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ ↓ 仍未解決 │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 🔵 Tier 4: 架構修復 (需要開發) │ │
│ │ 適用: 設計缺陷、技術債 │ │
│ │ 動作: create_issue, notify_team, schedule_fix │ │
│ │ 結果: 建立追蹤 Issue,排入 Sprint │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
9.4 AI 學習與 Playbook 自動更新
# apps/api/src/services/learning_service.py
"""
異常學習服務 - 從解決方案中學習
"""
class LearningService:
"""
學習每次修復的效果,自動更新 Playbook
"""
async def record_repair_result(
self,
anomaly_key: str,
repair_action: str,
success: bool,
root_cause: str | None,
fix_description: str | None,
):
"""
記錄修復結果,用於學習
"""
# 更新成功/失敗統計
if success:
await self._increment_success(anomaly_key, repair_action)
else:
await self._increment_failure(anomaly_key, repair_action)
# 如果找到根因且修復成功,更新 Playbook
if success and root_cause:
await self._update_playbook(
anomaly_signature=anomaly_key,
root_cause=root_cause,
fix_action=repair_action,
fix_description=fix_description,
)
async def get_recommended_fix(self, anomaly_key: str) -> dict:
"""
根據歷史學習,推薦最佳修復方案
"""
# 取得該異常的歷史修復統計
history = await self._get_repair_history(anomaly_key)
if not history:
return {'action': 'restart_pod', 'confidence': 0.3, 'tier': 1}
# 計算各動作的成功率
success_rates = {}
for action, stats in history.items():
if stats['total'] > 0:
success_rates[action] = stats['success'] / stats['total']
# 返回成功率最高的動作
if success_rates:
best_action = max(success_rates, key=success_rates.get)
return {
'action': best_action,
'confidence': success_rates[best_action],
'tier': self._get_action_tier(best_action),
'based_on': f"{history[best_action]['total']} 次歷史數據",
}
return {'action': 'restart_pod', 'confidence': 0.3, 'tier': 1}
9.5 Telegram 頻率告警格式
═══════════════════════════════════════
⚠️ 重複異常告警 (第 5 次)
═══════════════════════════════════════
📍 服務: awoooi-api
❌ 異常: OOM Killed
🔄 本月發生: 5 次
⏱️ 最近發生: 剛剛
📊 頻率統計:
• 1小時: 2 次
• 24小時: 5 次 ← 觸發升級
• 7天: 8 次
• 30天: 15 次
🔧 已嘗試修復:
• restart_pod: 3 次 (成功率 30%)
• scale_up: 1 次 (成功率 0%)
🧠 AI 分析:
「Memory Limit 設定過低,建議調整為 512Mi」
───────────────────────────────────────
🔴 建議: 永久修復 (Tier 3)
→ 調整 memory limit
[ ✅ 套用永久修復 ] [ 🔄 先重啟 ] [ ⏸️ 稍後 ]
═══════════════════════════════════════
9.6 實作清單
| 項目 | 優先級 | 工時 | 狀態 |
|---|---|---|---|
| AnomalyCounter 服務 | P0 | 4h | ⬜ |
| Redis 計數器整合 | P0 | 2h | ⬜ |
| 頻率閾值告警 | P0 | 2h | ⬜ |
| Telegram 頻率告警格式 | P0 | 2h | ⬜ |
| LearningService | P1 | 6h | ⬜ |
| Playbook 自動更新 | P1 | 4h | ⬜ |
| 修復成功率統計 | P1 | 2h | ⬜ |
| 根因修復動作庫 | P2 | 8h | ⬜ |
十、待統帥裁示
9.1 架構決策
| 問題 | 選項 | 首席架構師建議 |
|---|---|---|
| 監控中心是否獨立? | A. 整合到戰情室 / B. 獨立頁面 | A. 整合 |
| 角色分層優先級? | A. 先做 C-Level / B. 先強化 L2 | B. 先強化 L2 |
| 資料庫監控方式? | A. Exporter / B. 應用層探針 | A. Exporter |
9.2 優先級確認
| 階段 | 內容 | 預估工時 | 確認? |
|---|---|---|---|
| Phase 0 | 驗證修復 | 10min | ⬜ |
| Phase 1 | 消滅靜默失敗 | 9h | ⬜ |
| Phase 2 | 完善告警 | 12h | ⬜ |
| Phase 3 | 角色分層 | 18h | ⬜ |
9.3 資源分配
| 問題 | 選項 |
|---|---|
| 是否需要額外主機部署 Exporter? | 188 主機已有 Docker Compose,可直接加入 |
| Grafana 是否部署到 K3s? | 建議部署到 monitoring namespace |
文件狀態: DRAFT - 待統帥審核 下一步: 統帥確認後開始 Phase 1 實作