審查結果: - 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>
5.8 KiB
5.8 KiB
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 呼叫
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.pySettings 取得 - 支援 DI 測試替換
2. ErrorAnalyzerService (services/error_analyzer_service.py)
職責: AI 根因分析
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:
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-intl100% 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 規範
# ❌ 禁止 (即使有 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