Files
awoooi/docs/adr/ADR-022-sentry-integration-architecture.md
OG T 4f06115497
Some checks failed
E2E Health Check / e2e-health (push) Has been cancelled
CD Pipeline / build-and-deploy (push) Has been cancelled
docs: 首席架構師審查 - 前端內網 IP 禁令 (90/100)
審查結果:
- P0 安全修復: sudo 密碼改用 secret 
- P1 識別: Sentry DSN build-arg 待處理
- P2 識別: 3 項次要問題已記錄

已更新:
- Skills 01 v1.5: 前端建置禁止內網 IP
- Skills 04 v2.1: CD 安全規範 + 內網 IP 禁令
- ADR-022: 新增前端內網 IP 禁令章節
- MEMORY.md: 新增審查記錄索引

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-30 01:32:48 +08:00

175 lines
5.8 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.
# ADR-022: Sentry 整合架構
| 項目 | 內容 |
|------|------|
| **狀態** | ✅ 已採用 |
| **日期** | 2026-03-26 |
| **決策者** | 首席架構師 + 統帥 |
| **Phase** | Phase 10 |
## 背景
AWOOOI 需要完整的錯誤追蹤能力,補強 SignOz APM 的不足:
- SignOz 專注效能監控 (Traces, Metrics)
- Sentry 專注錯誤追蹤 (Stacktrace, Context, Session Replay)
## 決策
採用 **BFF + AI 分析** 三層架構:
```
┌─────────────────────────────────────────────────────────────┐
│ AWOOOI Web UI │
│ /errors 頁面 (React + next-intl) │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ AWOOOI API (BFF Layer) │
│ Router: /api/v1/errors/* │
│ Service: SentryService + ErrorAnalyzerService │
└─────────────────────────────────────────────────────────────┘
┌───────────────┼───────────────┐
▼ ▼
┌──────────────────────┐ ┌──────────────────────────┐
│ Sentry Self-Hosted │ │ OpenClaw LLM │
│ 192.168.0.110:9000 │ │ 192.168.0.188:8088 │
└──────────────────────┘ └──────────────────────────┘
```
## 架構組件
### 1. SentryService (`services/sentry_service.py`)
**職責**: 封裝 Sentry API 呼叫
```python
class SentryService:
async def list_projects() -> list[dict]
async def list_issues(query, limit, cursor) -> list[dict]
async def get_issue(issue_id) -> dict
async def get_issue_events(issue_id, limit, full) -> list[dict]
async def get_project_stats(stat, resolution) -> list
def get_issue_url(issue_id) -> str
```
**設計原則**:
- Singleton 模式
- 配置從 `core/config.py` Settings 取得
- 支援 DI 測試替換
### 2. ErrorAnalyzerService (`services/error_analyzer_service.py`)
**職責**: AI 根因分析
```python
class ErrorAnalyzerService:
async def analyze_error(
issue_id, title, level, culprit,
count, stacktrace, context
) -> tuple[ErrorAnalysisResult | None, str, bool]
```
**分析結果**:
- root_cause: 根因分析
- category: CODE_BUG | DEPENDENCY | CONFIGURATION | ...
- severity: LOW | MEDIUM | HIGH | CRITICAL
- fix_recommendation: 修復建議
- prevention: 預防措施
- confidence: 信心度 (0.0-1.0)
### 3. Router Layer (`api/v1/errors.py`)
**職責**: HTTP 轉發 (符合 leWOOOgo 積木化)
| 端點 | 功能 |
|------|------|
| `GET /stats` | 錯誤統計概覽 |
| `GET /issues` | 列出 Issues (分頁、過濾) |
| `GET /issues/{id}` | Issue 詳情 |
| `GET /trends` | 趨勢圖表數據 |
| `POST /issues/{id}/analyze` | 觸發 AI 分析 |
## 配置管理
所有 Sentry 配置集中於 `core/config.py`:
```python
SENTRY_SELF_HOSTED_URL: str = "http://192.168.0.110:9000"
SENTRY_ORG: str = "sentry"
SENTRY_PROJECT: str = "awoooi-api"
SENTRY_AUTH_TOKEN: str = "" # K8s Secret
```
## 與 SignOz 的關係
| 工具 | 職責 | 查看時機 |
|------|------|----------|
| **SignOz** | APM + Traces | 慢、效能問題 |
| **Sentry** | Error Tracking | 壞、錯誤堆疊 |
**互補策略**: 兩者皆部署,各司其職。
## 前端整合
- 使用 `next-intl` 100% i18n (禁止 hardcode)
- Nothing.tech 視覺規範 (白底、細邊框、無陰影)
- React Hook: `useErrors()` 自動刷新 60 秒
## 替代方案 (已拒絕)
| 方案 | 拒絕原因 |
|------|----------|
| 直接嵌入 Sentry Iframe | 違反視覺主權,無法自訂 UI |
| 前端直接呼叫 Sentry API | 違反 BFF 原則CORS 問題 |
| 只用 SignOz | 錯誤追蹤能力不足 |
## 後果
### 正面
- 完整的錯誤追蹤能力
- AI 輔助根因分析
- 符合 leWOOOgo 架構
### 負面
- 多一個服務需維護 (Sentry Self-Hosted)
- 額外的 API 呼叫延遲
## 🔴 前端內網 IP 禁令 (2026-03-30 補充)
### 問題
前端 Sentry DSN 使用內網 IP (`192.168.0.110:9000`) 會觸發瀏覽器「存取區域網路」權限對話框。
### 解決方案
**已採用**: Sentry Tunnel (方案 A)
```
前端 → /api/sentry-tunnel → Sentry Server (192.168.0.110:9000)
↑ 公網域名 ↑ Server-Side 內網
```
**配置位置**:
- `apps/web/src/app/api/sentry-tunnel/route.ts` - Tunnel 實作
- `apps/web/sentry.client.config.ts` - `tunnel: '/api/sentry-tunnel'`
### CD Pipeline 規範
```yaml
# ❌ 禁止 (即使有 Tunnel也不應暴露內網 IP)
--build-arg NEXT_PUBLIC_SENTRY_DSN=http://...@192.168.0.110:9000/2
# ✅ 不設定 (依賴 Tunnel 機制)
# 或使用公網域名反向代理
```
## 相關文件
- `project_phase10_arch_review.md` - 架構審查報告
- `project_sentry_full_integration.md` - 整合計畫
- `feedback_sentry_local_network.md` - 區域網路權限問題
- ADR-005: BFF Architecture
- ADR-006: AI Fallback Strategy