- ADR-037 監控增強架構 - MONITORING_MASTER_PLAN 主計畫 - MASTER_EXECUTION_SCHEDULE 執行排程 - Phase D/E/Worker HPA Runbooks Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
234 lines
6.4 KiB
Markdown
234 lines
6.4 KiB
Markdown
# RunBook: Phase E — SignOz Webhook Handler 生產部署
|
||
|
||
> **類型**: 操作型 RunBook
|
||
> **優先級**: 🔴 P0
|
||
> **建立**: 2026-03-29 12:35 (台北)
|
||
> **建立者**: Antigravity
|
||
> **工時預估**: 1.5–2 小時
|
||
> **前置條件**: SignOz UI 可在 http://192.168.0.188:3301 正常訪問
|
||
|
||
---
|
||
|
||
## 背景與現況
|
||
|
||
### 🔍 精確現況診斷
|
||
|
||
```
|
||
signoz_webhook.py → 完整實作 (363 行,含 4 步驟完整流程)
|
||
main.py:419 → 已正確路由 include_router(signoz_webhook_v1.router)
|
||
端點:POST /api/v1/webhooks/signoz/alert ✅ 已可接收
|
||
問題:SignOz 告警規則未指向此 Webhook
|
||
```
|
||
|
||
**唯一阻塞點**:SignOz 告警規則 (`ops/signoz/alerting/rules.yaml`) 的 `webhook` 欄位尚未設定或未部署到 SignOz 主機。
|
||
|
||
### 完整資料流
|
||
|
||
```
|
||
SignOz 偵測到異常 (Error Rate / Latency / No Traces)
|
||
↓
|
||
SignOz Alert Manager 觸發告警
|
||
↓
|
||
POST http://192.168.0.120:32334/api/v1/webhooks/signoz/alert ← 需要配置
|
||
↓
|
||
process_signoz_alert() [Background Task]
|
||
↓
|
||
├── AnomalyCounter 記錄頻率 (ADR-037) ✅
|
||
├── IncidentService 建立事件 ✅
|
||
├── ApprovalService 建立簽核 ✅
|
||
└── TelegramGateway 發送通知 ✅
|
||
```
|
||
|
||
---
|
||
|
||
## Step 1: 確認 API 端點可達
|
||
|
||
```bash
|
||
# 從 188 主機測試 SignOz Webhook 端點
|
||
curl -s http://192.168.0.120:32334/api/v1/webhooks/signoz/health
|
||
# 預期:{"status": "ok", "service": "signoz-webhook", "timestamp": "..."}
|
||
|
||
# 如端點不通,確認 Pod 狀態
|
||
kubectl get pod -n awoooi-prod -l app=awoooi-api
|
||
```
|
||
|
||
---
|
||
|
||
## Step 2: 設定 SignOz 告警規則
|
||
|
||
### 2.1 確認 ops/signoz/alerting/rules.yaml 已建立
|
||
|
||
```bash
|
||
# 確認檔案存在
|
||
ls /Users/ogt/awoooi/ops/signoz/alerting/
|
||
# 如不存在,從 IMPLEMENTATION_STEPS_REMAINING_PHASES.md 的 Phase E 代碼複製
|
||
```
|
||
|
||
### 2.2 部署告警規則到 SignOz 主機
|
||
|
||
```bash
|
||
# 登入 SignOz 主機
|
||
ssh root@192.168.0.188
|
||
|
||
# 確認 SignOz 告警配置目錄
|
||
docker inspect signoz-query-service | grep -A5 "Mounts"
|
||
# 常見路徑:/opt/signoz/config/ 或 /data/signoz/
|
||
|
||
# 複製告警規則(從本機)
|
||
# 先在本機執行:
|
||
scp /Users/ogt/awoooi/ops/signoz/alerting/rules.yaml \
|
||
root@192.168.0.188:/opt/signoz/config/alerting/
|
||
|
||
# 在 188 主機重啟 SignOz Alert Manager(不重啟整個 SignOz)
|
||
docker restart signoz-alert-manager 2>/dev/null || \
|
||
docker restart signoz # 若是單容器部署
|
||
```
|
||
|
||
### 2.3 透過 SignOz API 驗證規則載入
|
||
|
||
```bash
|
||
# 在 188 主機執行
|
||
curl -s http://localhost:3301/api/v3/alerts/rules | python3 -m json.tool | head -40
|
||
# 預期看到 APIHighErrorRate, APIHighLatencyP99 等規則名稱
|
||
```
|
||
|
||
---
|
||
|
||
## Step 3: 設定 SignOz Webhook Channel
|
||
|
||
SignOz 告警通知支援 Webhook Channel,需要透過 SignOz Web UI 或 API 設定。
|
||
|
||
### 3.1 透過 SignOz UI 設定(推薦)
|
||
|
||
```
|
||
瀏覽器開啟:http://192.168.0.188:3301
|
||
路徑:Settings → Alert Channels → New Channel
|
||
|
||
類型:Webhook
|
||
名稱:AWOOOI-API
|
||
URL:http://192.168.0.120:32334/api/v1/webhooks/signoz/alert
|
||
Send resolved notifications:☑ (可選)
|
||
```
|
||
|
||
### 3.2 透過 API 設定(腳本化)
|
||
|
||
```bash
|
||
# 在 188 主機執行
|
||
curl -s -X POST http://localhost:3301/api/v1/channels \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"name": "AWOOOI-API",
|
||
"type": "webhook",
|
||
"data": {
|
||
"webhook_url": "http://192.168.0.120:32334/api/v1/webhooks/signoz/alert"
|
||
}
|
||
}'
|
||
# 預期返回 channel ID
|
||
```
|
||
|
||
---
|
||
|
||
## Step 4: 建立測試告警規則
|
||
|
||
為了驗證整個鏈路,建立一個低閾值測試規則:
|
||
|
||
```bash
|
||
# 在 188 主機的 SignOz 目錄建立測試規則
|
||
cat > /tmp/test-alert.yaml << 'EOF'
|
||
groups:
|
||
- name: e2e_test
|
||
rules:
|
||
- alert: AWOOOI_E2E_SMOKE_TEST
|
||
expr: up{job="awoooi-api"} == 1 # 永遠觸發(API 存活時)
|
||
for: 1m
|
||
labels:
|
||
severity: info
|
||
source: signoz
|
||
test: "true"
|
||
annotations:
|
||
summary: "E2E Smoke Test - 請忽略"
|
||
description: "這是 AWOOOI 告警鏈路的自動測試"
|
||
webhook: "http://192.168.0.120:32334/api/v1/webhooks/signoz/alert"
|
||
EOF
|
||
```
|
||
|
||
---
|
||
|
||
## Step 5: 端到端驗證
|
||
|
||
### 5.1 手動觸發測試
|
||
|
||
```bash
|
||
# 直接向 AWOOOI API 發送模擬 SignOz 告警
|
||
curl -s -X POST http://192.168.0.120:32334/api/v1/webhooks/signoz/alert \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"alertname": "APIHighErrorRate",
|
||
"status": "firing",
|
||
"labels": {
|
||
"alertname": "APIHighErrorRate",
|
||
"severity": "critical",
|
||
"service_name": "awoooi-api",
|
||
"source": "signoz"
|
||
},
|
||
"annotations": {
|
||
"summary": "API 錯誤率 > 5%",
|
||
"description": "服務 awoooi-api 錯誤率超標,這是一個測試告警"
|
||
},
|
||
"startsAt": "2026-03-29T12:00:00Z"
|
||
}'
|
||
|
||
# 預期回應
|
||
# {"status": "ok", "processed": 1, "results": [{"status": "accepted", "alert_name": "APIHighErrorRate"}]}
|
||
```
|
||
|
||
### 5.2 確認 Telegram 收到告警
|
||
|
||
```
|
||
預期在 Telegram Bot 中收到:
|
||
═══════════════════════════
|
||
📊 SignOz: APIHighErrorRate
|
||
═══════════════════════════
|
||
服務:awoooi-api
|
||
摘要:API 錯誤率 > 5%
|
||
[ Y 確認 ] [ N 忽略 ]
|
||
```
|
||
|
||
### 5.3 確認 API 日誌
|
||
|
||
```bash
|
||
kubectl logs -n awoooi-prod \
|
||
$(kubectl get pod -n awoooi-prod -l app=awoooi-api -o name | head -1) \
|
||
--tail=30 | grep -i signoz
|
||
|
||
# 預期看到:
|
||
# signoz_alert_received payload=...
|
||
# signoz_anomaly_recorded alert_name=APIHighErrorRate
|
||
# signoz_alert_processed alert_name=APIHighErrorRate incident_id=xxx
|
||
# signoz_telegram_sent approval_id=xxx
|
||
```
|
||
|
||
---
|
||
|
||
## 驗收標準
|
||
|
||
| 項目 | 通過條件 |
|
||
|------|---------|
|
||
| Webhook 端點可達 | `curl .../signoz/health` 返回 200 |
|
||
| SignOz 規則載入 | `/api/v3/alerts/rules` 包含 `APIHighErrorRate` |
|
||
| 手動測試正常 | 回應 `{"status": "ok"}` |
|
||
| Telegram 通知 | 成功收到告警卡片 |
|
||
| Incident 建立 | DB 中可查到 `source=signoz` 的 Incident |
|
||
| Approval 建立 | `GET /api/v1/approvals` 顯示新 Approval |
|
||
|
||
---
|
||
|
||
## 常見問題排除
|
||
|
||
| 症狀 | 診斷 | 解法 |
|
||
|------|------|------|
|
||
| Webhook 404 | `curl .../signoz/health` | 確認主機是 32334 而非 8089 |
|
||
| SignOz 規則不觸發 | SignOz UI → Alerts 頁 | 確認 Prometheus 端點可抓到 awoooi-api metrics |
|
||
| Telegram 未收到 | 查 API 日誌 | 確認 `OPENCLAW_TG_BOT_TOKEN` Secret 已注入 |
|
||
| Incident 建立失敗 | 查 API 日誌 `incident_creation_failed` | 確認 PostgreSQL 連線正常 |
|