結論先講

很多團隊的「監控」是這樣的:裝了 Grafana,有幾個 dashboard,偶爾有人上去看一眼。出事了才發現沒有告警、或者告警太多沒人理。

告警不等於監控。 好的監控系統需要回答三個問題:系統現在健不健康(Metrics)、剛才發生了什麼事(Logs)、問題發生在哪裡(Traces)。然後在問題影響使用者之前,用適當的方式通知適當的人。


體檢清單

1. 可觀測性三根支柱

          ┌─────────────────────────────────────┐
          │        Observability                │
          │                                     │
          │  ┌─────────┐ ┌──────┐ ┌──────────┐  │
          │  │ Metrics │ │ Logs │ │  Traces  │  │
          │  │ 數值指標 │ │ 事件 │ │ 請求追蹤 │  │
          │  └─────────┘ └──────┘ └──────────┘  │
          └─────────────────────────────────────┘
支柱回答的問題範例工具
Metrics現在怎樣?趨勢如何?CPU 80%、QPS 500、P99 200msPrometheus、Datadog
Logs發生了什麼?為什麼?Error: Connection refusedELK、Loki、CloudWatch
Traces請求經過了哪些服務?UserAPI → OrderService → PaymentGW (350ms)Jaeger、Tempo
# OpenTelemetry 設定(統一三根支柱)
# otel-collector-config.yaml
receivers:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317
 
exporters:
  prometheus:
    endpoint: 0.0.0.0:8889
  loki:
    endpoint: http://loki:3100/loki/api/v1/push
  otlp/tempo:
    endpoint: tempo:4317
 
service:
  pipelines:
    metrics:
      receivers: [otlp]
      exporters: [prometheus]
    logs:
      receivers: [otlp]
      exporters: [loki]
    traces:
      receivers: [otlp]
      exporters: [otlp/tempo]
  • 三根支柱都有覆蓋
  • 資料之間可以關聯(trace ID 串起 metrics 和 logs)
  • 使用 OpenTelemetry 做統一的 instrumentation

2. SLI / SLO / SLA

先搞清楚這三個東西:

概念全稱是什麼範例
SLIService Level Indicator衡量指標99.5% 的請求在 200ms 內回應
SLOService Level Objective內部目標每月 SLI 達到 99.9%
SLAService Level Agreement對外合約低於 99.9% 就賠錢
SLI(量測) → SLO(目標) → SLA(合約)
  越來越嚴格 →
  • 定義核心服務的 SLI
  • 設定 SLO(通常比 SLA 嚴格一些)
  • 有 error budget(SLO 剩餘的容錯空間)
  • 定期 review SLO 達成狀況
# SLO 計算範例
# SLO: 99.9% availability per month
# 一個月 30 天 = 43,200 分鐘
# 允許停機時間 = 43,200 * 0.001 = 43.2 分鐘
 
# Error budget = 43.2 分鐘
# 已用 error budget = 15 分鐘(本月兩次小 incident)
# 剩餘 error budget = 28.2 分鐘

3. Dashboard 設計(Golden Signals)

Google SRE 定義的四個黃金信號:

信號衡量什麼PromQL 範例
Latency回應時間histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m]))
Traffic請求量sum(rate(http_requests_total[5m]))
Errors錯誤率sum(rate(http_requests_total{status=~"5.."}[5m])) / sum(rate(http_requests_total[5m]))
Saturation資源飽和度container_memory_usage_bytes / container_spec_memory_limit_bytes
  • 每個服務有 dashboard 顯示四個黃金信號
  • Dashboard 有不同時間範圍(1h、24h、7d)
  • 有全局 overview dashboard
  • Dashboard 有組織(不是 100 個散落的面板)

4. 告警疲勞防治

告警太多跟沒有告警一樣糟糕。

壞的告警:
- CPU > 70% → 叫人起床(但它每天都在 70% 附近)
- 任何 5xx → 告警(偶爾的 5xx 是正常的)
- Disk > 80% → 告警(但磁碟成長率是每月 1%)

好的告警:
- Error rate > 1% 持續 5 分鐘 → 告警
- P99 latency > 2s 持續 10 分鐘 → 告警
- Disk 預計 48 小時內滿 → 告警
  • 每個告警都有對應的 action(收到告警知道要做什麼)
  • 使用 rate 而不是 absolute value
  • 有合理的閾值和持續時間(避免 flapping)
  • 定期 review 告警規則(每季至少一次)
  • 追蹤 alert-to-action ratio(真正需要處理的比例)

5. 告警分級與通知

等級定義通知方式回應時間
P1 Critical服務完全中斷電話 + 簡訊 + Slack15 分鐘
P2 High部分功能異常Slack + Email1 小時
P3 Medium效能下降Slack4 小時
P4 Low非緊急Email / Ticket次日
  • 告警有分級
  • 不同等級有不同通知方式
  • P1 一定有人收到(不是只發 Slack 訊息)

6. 值班輪值(On-call Rotation)

Week 1: Alice (primary), Bob (secondary)
Week 2: Bob (primary), Carol (secondary)
Week 3: Carol (primary), Alice (secondary)
  • 有明確的值班表
  • 有 primary 和 secondary on-call
  • 值班期間有額外補償
  • 有 escalation policy(primary 沒回應就找 secondary)
工具用途
PagerDuty值班管理、告警路由
OpsGenie值班管理(Atlassian 生態)
Grafana OnCall開源值班管理
自己用 Slack Bot小團隊可以

7. Incident Response

一個標準的 incident 處理流程:

1. 偵測(Alert fired)
2. 確認(Acknowledge)
3. 分類(P1/P2/P3)
4. 組建 War Room(P1 才需要)
5. 診斷(看 metrics, logs, traces)
6. 修復(hotfix, rollback, config change)
7. 驗證(確認恢復正常)
8. 通知(跟利害關係人更新狀態)
9. 事後檢討(Postmortem)
  • 有文件化的 incident response 流程
  • 有 incident channel(Slack/Teams 專用頻道)
  • 有 status page 向使用者溝通
  • 有 incident commander 角色

8. 事後檢討(Postmortem)

Blameless postmortem — 找原因不找戰犯。

一份好的 postmortem 應該包含:

# Incident Report: API 回應時間飆升
 
## 摘要
- 日期:2026-03-15 14:00 - 14:45 (UTC+8)
- 影響:API P99 latency 從 200ms 飆升到 5s,影響約 30% 使用者
- 等級:P2
 
## 時間線
- 14:00 部署 v1.5.2
- 14:05 告警觸發:P99 > 2s
- 14:10 on-call 確認,開始調查
- 14:20 發現新 SQL query 缺少 index
- 14:30 rollback 到 v1.5.1
- 14:35 latency 恢復正常
- 14:45 確認穩定,incident 關閉
 
## 根因
新功能的 SQL query 在 users 表做全表掃描(缺少 index)
 
## 改善措施
1. [ ] 加上缺少的 index
2. [ ] CI 加入 slow query 檢測
3. [ ] 部署後自動監控 latency 變化
  • 每個 P1/P2 incident 都有 postmortem
  • Postmortem 在一週內完成
  • Action items 有追蹤(不是寫完就忘了)
  • 定期分享 postmortem(團隊學習)

工具比較

全家桶 vs 自組

方案組合優點缺點月費(估算)
自組開源Prometheus + Grafana + Loki + Tempo免費、可控維護成本$0 + 運維人力
Datadog全包省事、UX 好$15-23/host/month
New Relic全包免費額度大方超量就貴免費 100GB/month
Elastic CloudELK Stack搜尋強大資源吃很兇$95+/month

適合你的方案

  • 1-3 人小團隊:New Relic(免費額度)或 Grafana Cloud(免費額度)
  • 5-20 人中團隊:Datadog 或自組 Prometheus + Grafana
  • 20+ 人大團隊:Datadog 或自組全套(有專人維護)

實戰:Prometheus Alert Rules

# alerts.yml
groups:
  - name: web-app
    rules:
      - alert: HighErrorRate
        expr: |
          sum(rate(http_requests_total{status=~"5.."}[5m]))
          / sum(rate(http_requests_total[5m])) > 0.01
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "Error rate > 1% for 5 minutes"
          runbook: "https://wiki/runbooks/high-error-rate"
 
      - alert: HighLatency
        expr: |
          histogram_quantile(0.99,
            sum(rate(http_request_duration_seconds_bucket[5m])) by (le)
          ) > 2
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "P99 latency > 2s for 10 minutes"
 
      - alert: DiskWillFull
        expr: |
          predict_linear(node_filesystem_avail_bytes[6h], 48*3600) < 0
        labels:
          severity: warning
        annotations:
          summary: "Disk predicted to be full in 48 hours"

FAQ

Q1: 小專案需要三根支柱都做嗎?

不用。先做 Metrics(Prometheus + Grafana 或雲端監控),再做集中式 Logs。Traces 等你有微服務架構再加。但從一開始就用 OpenTelemetry 做 instrumentation,以後要加支柱會很容易。

Q2: 告警規則怎麼訂才不會太多?

一個原則:每個告警收到時,你都應該需要做些什麼。 如果一個告警收到後的標準動作是「看一眼就關掉」,那這個告警就該拿掉或調整閾值。

Q3: SLO 要設多高?

不要一開始就設 99.99%。先從 99.5% 或 99.9% 開始,觀察幾個月後再調整。設太高會讓團隊壓力很大且沒有 error budget 做實驗。

Q4: Postmortem 真的不追究責任嗎?

真的。Blameless postmortem 的精神是:人會犯錯是正常的,系統應該有機制防止人為錯誤造成大規模影響。如果一個工程師的操作就能搞掛整個系統,那是系統的問題,不是人的問題。

Q5: Datadog 好貴,有什麼替代方案?

Grafana Cloud 有不錯的免費額度(10K metrics、50GB logs、50GB traces)。自架的話,Prometheus + Grafana + Loki + Tempo 全套開源免費,但你要有人力維護。New Relic 給 100GB/month 免費額度也很大方。


系列導航