Phase S 技術債修復 (首席架構師審查 82→完整): - S-01: generate_alert_fingerprint 移至 AlertAnalyzer.generate_fingerprint() staticmethod - S-04: 移除 Pydantic v2 deprecated json_encoders (直接用原生 datetime 序列化) Sentry MCP 整合 (Phase 23): - ADR-048: Sentry→OpenClaw AI Triage 架構決策 - sentry_webhook_service.py: parse/analyze/create_incident/build_message Service 層 - config.py: SENTRY_WEBHOOK_SECRET (Fail-Closed HMAC-SHA256) Playwright MCP 整合 (短期): - smoke.spec.ts: 5 頁面 E2E smoke test (home/dashboard/incidents/approvals/terminal) - cd.yaml: E2E Smoke Test 步驟 + Telegram 🎭 Smoke 狀態通知 長期規劃 ADR: - ADR-049: Figma Code Connect 設計系統同步 - ADR-050: Telegram 互動式 Incident 2.0 (6鍵 Inline Keyboard) - ADR-051: Context7 依賴升級顧問 (Next.js 14→15, FastAPI 0.115→0.128) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
155 lines
4.9 KiB
Markdown
155 lines
4.9 KiB
Markdown
# ADR-048: Sentry → OpenClaw AI Triage 自動化
|
||
|
||
**狀態**: 已實作 (Phase 23)
|
||
**日期**: 2026-04-01 (台北時區)
|
||
**作者**: Claude Code
|
||
**關聯**: Phase 10 (Sentry 基礎整合), Phase 21 (ADR-037 異常頻率統計), Phase 22 (ADR-044 Nemotron 協作)
|
||
|
||
---
|
||
|
||
## 問題陳述
|
||
|
||
Sentry 持續捕獲後端 Python 與前端 Next.js 錯誤,但缺乏自動化 triage 流程:
|
||
|
||
- 工程師需手動查看 Sentry Issue 並判斷嚴重程度
|
||
- 錯誤發生後沒有即時通知渠道(Telegram)
|
||
- 無法自動關聯歷史頻率判斷是否為常態錯誤或異常升級
|
||
- 沒有 AI 輔助根因分析,所有診斷依賴人工
|
||
|
||
**目標**:Sentry 新錯誤觸發時,自動完成 triage → AI 分析 → Incident 建立 → Telegram 通知,無需人工介入。
|
||
|
||
---
|
||
|
||
## 決策
|
||
|
||
透過 **Sentry Issue Alert Webhook** 整合 OpenClaw AI Triage 流程。
|
||
|
||
### 選擇 Webhook 而非輪詢的原因
|
||
|
||
| 方案 | 延遲 | 基礎設施成本 | 複雜度 |
|
||
|------|------|-------------|--------|
|
||
| Webhook (本方案) | 近即時 (<2s) | 無額外組件 | 低 |
|
||
| 輪詢 (每分鐘) | 最高 60s | 需 scheduler | 中 |
|
||
| Sentry Alerts API | 近即時 | 需 OAuth | 高 |
|
||
|
||
---
|
||
|
||
## 架構
|
||
|
||
```
|
||
自架 Sentry (192.168.0.110:9000)
|
||
│ Issue Alert Webhook (action=triggered, level=error/fatal)
|
||
▼
|
||
AWOOOI API POST /api/v1/webhooks/sentry/error
|
||
│
|
||
├─ [同步] 去重檢查 (Redis, 10min TTL)
|
||
├─ [同步] Level 過濾 (只處理 error/fatal)
|
||
│
|
||
└─ [背景 BackgroundTask]
|
||
│
|
||
├─ 1. AnomalyCounter.record_anomaly() → 頻率統計
|
||
│ (ADR-037: 1h/24h/7d/30d + 升級判斷)
|
||
│
|
||
├─ 2. OpenClawHttpService.analyze_error()
|
||
│ Circuit Breaker (ADR-038) + Semaphore
|
||
│ 優先 Ollama (本地) → Fallback Claude
|
||
│ → ErrorAnalysisResult (root_cause, fix, prevention, confidence)
|
||
│
|
||
├─ 3. ApprovalService.create_approval()
|
||
│ 風險等級 = Sentry Level + 頻率升級
|
||
│ → Approval ID
|
||
│
|
||
├─ 4. TelegramGateway.send_approval_card()
|
||
│ 格式: 🐛 SENTRY 錯誤告警 + OpenClaw 分析 + [Y/n]
|
||
│
|
||
└─ 5. SentryService.post_issue_comment()
|
||
AI 分析結果回寫至 Sentry Issue
|
||
```
|
||
|
||
### Sentry Cloud (wooo-92.sentry.io) 前端整合
|
||
|
||
前端 Next.js 錯誤透過 Sentry Cloud 捕獲,使用相同 Webhook 格式。
|
||
在 Sentry Cloud 配置 Alert Rule 指向同一端點:
|
||
`POST https://awoooi.wooo.work/api/v1/webhooks/sentry/error`
|
||
|
||
---
|
||
|
||
## 實作細節
|
||
|
||
### 端點
|
||
|
||
```
|
||
POST /api/v1/webhooks/sentry/error
|
||
```
|
||
|
||
### 觸發條件 (Sentry Alert Rule 配置)
|
||
|
||
- action: `triggered`
|
||
- level: `error` 或 `fatal`
|
||
|
||
### 去重策略
|
||
|
||
- Redis key: `sentry_dedup:{issue_id}`
|
||
- TTL: 600 秒 (10 分鐘)
|
||
- 同一 issue 10 分鐘內不重複處理
|
||
|
||
### 風險等級映射
|
||
|
||
| Sentry Level | 基礎風險 | 頻率升級 (ESCALATE) | 頻率升級 (PERMANENT_FIX) |
|
||
|-------------|---------|-------------------|------------------------|
|
||
| fatal | CRITICAL | CRITICAL | CRITICAL |
|
||
| error | HIGH | HIGH | CRITICAL |
|
||
| warning | MEDIUM | HIGH | CRITICAL |
|
||
|
||
### Webhook Secret 驗證
|
||
|
||
- Config: `SENTRY_WEBHOOK_SECRET`
|
||
- Header: `sentry-hook-signature` (HMAC-SHA256)
|
||
- 生產環境未設定 → Fail-Closed 拒絕
|
||
- 開發環境未設定 → 允許跳過 (僅供測試)
|
||
|
||
---
|
||
|
||
## 影響評估
|
||
|
||
### 正向影響
|
||
|
||
- **MTTR 縮短**: AI 自動根因分析,工程師無需從 log 推斷
|
||
- **告警品質提升**: 頻率統計避免重複告警噪音
|
||
- **可審計性**: 所有 Sentry Issue 自動建立 Approval 記錄
|
||
- **回饋閉環**: AI 分析結果回寫 Sentry Comment,歷史可查
|
||
|
||
### 風險與緩解
|
||
|
||
| 風險 | 緩解措施 |
|
||
|------|---------|
|
||
| OpenClaw 不可用 | Circuit Breaker (ADR-038) + 降級:無 AI 分析仍建立 Approval |
|
||
| Telegram 傳送失敗 | Exception catch + log,不中斷主流程 |
|
||
| Redis 不可用 | check_dedup 失敗 → 預設 True(允許處理,可能重複) |
|
||
| Sentry API Token 未設 | Comment 回寫跳過,其他流程不受影響 |
|
||
|
||
### 不影響項目
|
||
|
||
- 現有 Alertmanager → AWOOOI → Telegram 流程不變
|
||
- 現有 GitHub Webhook 整合不變
|
||
- Sentry SDK 錯誤捕獲邏輯不變
|
||
|
||
---
|
||
|
||
## 相關檔案
|
||
|
||
- **Router**: `apps/api/src/api/v1/sentry_webhook.py`
|
||
- **Service (Sentry API)**: `apps/api/src/services/sentry_service.py`
|
||
- **Service (Webhook 業務邏輯)**: `apps/api/src/services/sentry_webhook_service.py`
|
||
- **Config**: `apps/api/src/core/config.py` (`SENTRY_WEBHOOK_SECRET`)
|
||
- **Circuit Breaker**: `apps/api/src/core/circuit_breaker.py` (ADR-038)
|
||
|
||
---
|
||
|
||
## 後續工作
|
||
|
||
- [ ] 在自架 Sentry 配置 Issue Alert Rule 指向 `/webhooks/sentry/error`
|
||
- [ ] 在 Sentry Cloud 配置相同 Alert Rule
|
||
- [ ] K8s Secret 注入 `SENTRY_WEBHOOK_SECRET`
|
||
- [ ] E2E 測試:手動觸發 Sentry Issue → 驗證 Telegram 收到告警
|