Files
awoooi/docs/proposals/MONITORING_STRATEGIC_PLANNING.md
OG T 1e7c5134fe docs: 新增異常頻率統計與根本修復章節 (統帥反饋)
- 異常頻率追蹤架構 (Redis 計數器 + 滑動窗口)
- 修復策略分級 (Tier 1-4: 重啟→緩解→根因→架構)
- AI 學習服務 (LearningService + Playbook 自動更新)
- Telegram 頻率告警格式 (重複次數 + 成功率統計)
- 實作清單 (P0: 22h, P1: 12h, P2: 8h)

🔴 關鍵觀點: 重啟只是治標,不是治本

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-29 02:04:10 +08:00

942 lines
55 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 事件時間軸報告 (缺失的關鍵功能)
```markdown
═══════════════════════════════════════════════════════════════
📋 事件報告: 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 分離
| 方案 | 優點 | 缺點 | 建議 |
|------|------|------|------|
| **整合** (在現有戰情室擴展) | 單一入口、用戶熟悉 | 可能變得臃腫 | ✅ **推薦** |
| **分離** (獨立監控中心) | 清晰分工 | 維護成本高、用戶需切換 | ❌ |
**首席架構師建議**: **整合方案**
理由:
1. 現有戰情室已有完整基礎 (Approval、Incident、Timeline)
2. 監控與處理應該在同一畫面 (減少上下文切換)
3. 透過 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 計數器設計
```python
# 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 自動更新
```python
# 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 實作