程式仍在執行不代表功能可以正常完成。單一健康檢查成功,也無法說明錯誤是否持續增加、處理是否變慢,或相依項目是否已經影響結果。監控要先定義正常狀態,再收集足以判斷偏差的資料,最後把需要處理的問題轉成可以採取行動的告警。
本章使用「服務」統稱需要持續觀察的執行單位。目標系統如果是批次程式、桌面程式或其他形式,仍可按照實際使用方式改用完成率、等待時間、輸出正確性或最近成功時間等指標。
「正常」必須能被檢查。每項重要功能應該先連回已確認的需求、風險及穩定條件,再選擇監控資料。
| 判斷面向 | 要回答的問題 | 可觀察結果範例 |
|---|---|---|
| 功能結果 | 重要工作是否產生正確輸出與狀態變化? | 成功、拒絕、部分完成及失敗數量符合預期 |
| 處理時間 | 從開始到完成可以等待多久? | 延遲百分位或工作等待時間未超過門檻 |
| 處理能力 | 指定時間內要完成多少工作? | 完成率、處理量與積壓維持在允許範圍 |
| 可用狀態 | 哪些功能目前能被使用? | 必要功能的檢查結果與可用比例符合目標 |
| 復原狀態 | 發生失敗後多久要恢復? | 從偵測到恢復的時間未超過限制 |
| 資料結果 | 延遲、重試或遷移後內容是否仍正確? | 來源與目標的版本、數量或規則檢查一致 |
可以使用服務水準指標(Service Level Indicator, SLI)表示實際量測結果,再以服務水準目標(Service Level Objective, SLO)記錄指定期間內要達到的門檻。SLI 與 SLO 要採用使用對象能感受到的結果,例如成功比例與延遲,而非只觀察內部執行資源。
Google SRE 的四項黃金訊號包含延遲、流量(Traffic)、錯誤與飽和度。這組訊號源自持續提供回應的服務,套用至其他系統時要改成符合實際工作的量測方式。
| 黃金訊號 | 通用判斷問題 | 可能的量測方式 |
|---|---|---|
| 延遲 | 一項工作需要多久才完成? | 成功與失敗結果分開計算的處理時間、等待時間與百分位數 |
| 流量 | 系統目前承受多少需求? | 如果系統處理網路請求,使用請求率。其他系統可使用操作數、工作數、事件數或資料量 |
| 錯誤 | 有多少工作未產生預期結果? | 錯誤碼比例、失敗工作數、逾時、拒絕與不一致結果 |
| 飽和度 | 哪項有限資源接近處理上限? | 佇列積壓、連線使用比例、並行工作限制與節流事件 |
平均值可能掩蓋少數極慢或連續失敗的操作。延遲應該觀察符合需求的百分位數,錯誤則要按照類型、功能與版本分類。飽和度也要包含即將超過限制的趨勢,避免等到功能失敗後才發現問題。
監控清單要按照系統實際構成建立,不需要預設所有系統都有相同元件。
| 執行方式或構成 | 建議觀察內容 |
|---|---|
| 立即回應的操作 | 接受數、成功率、延遲、逾時、拒絕與同時處理數 |
| 批次或排程工作 | 最近成功時間、執行時間、處理筆數、失敗位置與重跑結果 |
| 背景工作 | 佇列深度、最舊工作等待時間、完成率、重試與死信數量 |
| 保存機制 | 讀寫等待、連線使用、衝突、錯誤、容量限制與復原狀態 |
| 快取 | 命中、未命中、到期、淘汰、來源負載與過期內容時間 |
| 外部相依項目 | 呼叫量、延遲、錯誤、逾時、斷路狀態與降級結果 |
| 資料同步 | 發佈、消費、積壓、重試、死信與最終資料版本差異 |
每個指標都要回答一個實際問題。無法連回需求、風險、容量限制或處理動作的資料,可以先保留在除錯記錄,不必全部轉成長期指標。
遙測(Telemetry)可以從不同角度描述同一項操作。OpenTelemetry 的訊號說明將追蹤、指標與記錄列為不同訊號,它們適合處理的問題也不同。
| 訊號 | 適合回答的問題 | 不適合單獨承擔的工作 |
|---|---|---|
| 結構化記錄 | 某次事件在甚麼時間、版本與條件下發生? | 直接判斷長期比例與趨勢 |
| 指標(Metrics) | 指定期間內的數量、比例、分布與目前值如何變化? | 保存每次操作的完整細節 |
| 分散式追蹤(Distributed Tracing) | 一次操作經過哪些處理步驟,時間花在哪裡? | 取代所有事件與長期彙整資料 |
| 健康檢查 | 程式目前是否存活、就緒或能完成最小功能? | 證明完整功能、容量與資料結果都正確 |
已經採用 operationId 的系統,可以用它串連錯誤結果、記錄與追蹤。指標則要使用有限且穩定的維度聚合資料,不能把每次操作的識別碼直接放進指標標籤。
異常事件已經具有穩定欄位時,可以按照時間範圍與結果分類產生指標。常見轉換如下:
| 事件欄位 | 指標用途 | 注意事項 |
|---|---|---|
eventName |
區分執行階段或事件種類 | 名稱集合要受控,避免在名稱中加入動態內容 |
errorCode |
計算可預期錯誤與未預期例外 | 只使用穩定錯誤碼,不直接使用完整錯誤訊息 |
outcome |
計算成功、拒絕、失敗或部分完成比例 | 狀態值要有固定定義 |
component |
找出受影響的組成項目 | 只使用已定義且數量有限的名稱 |
version |
比較部署前後的錯誤與延遲 | 同時保存成品識別,避免版本名稱重複使用 |
riskId |
追蹤已確認安全或穩定風險的實際事件 | 只在事件已明確連回風險時使用 |
operationId |
從彙整結果查回單次操作 | 保留於記錄與追蹤,不作為指標標籤 |
例如,errorCode 在十分鐘內持續增加可以形成錯誤率指標,再由告警連結查詢該時間範圍的記錄。相關人員可以從代表性事件取得 operationId,繼續查看同一次操作的處理路徑。這樣既能發現整體變化,也能保留調查單次問題的入口。
相同指標的每組標籤值都會形成獨立時間序列。把 operationId、原始路徑、錯誤訊息或其他不受限制的內容放入標籤,會讓序列數量持續增加。Prometheus 的指標命名建議也提醒避免使用識別碼等高基數(High Cardinality)內容作為標籤。
建立指標時應該:
指標值為零與沒有收到資料代表不同情況。告警及儀表板要能辨識程式沒有工作、收集流程中斷與實際沒有錯誤,避免把遙測缺口解讀成正常狀態。
不同健康檢查要觸發不同動作。
| 檢查 | 要回答的問題 | 常見處理 |
|---|---|---|
| 啟動檢查 | 程式是否仍在允許的啟動期間內? | 繼續等待,或在超過期限後停止啟動 |
| 存活檢查(Liveness Check) | 程式是否已進入無法自行恢復的狀態? | 由部署環境按照設定重新啟動 |
| 就緒檢查(Readiness Check) | 程式目前是否能接受新的工作? | 暫停分派新工作,保留程序以便恢復 |
| 功能健康檢查 | 最小關鍵案例是否產生預期結果? | 阻止部署完成,或啟動人工調查與復原 |
如果部署平臺支援自動重新啟動與工作分派,可以按照平臺語意提供對應檢查。Kubernetes 的探測說明指出,存活探測失敗可觸發重新啟動,就緒探測失敗則停止把工作送至該 Pod。其他部署方式仍可沿用問題分類,但處理動作要按照實際能力設計。
存活檢查不適合依賴所有外部項目。外部相依暫時失效時重新啟動大量正常程序,可能擴大問題。健康檢查應該快速、具有限時,並且避免產生資料變更。完整功能驗證則由冒煙測試、合成操作或其他受控案例負責。
儀表板應該回答「目前是否正常」、「影響多大」與「甚麼時候開始改變」。首頁可以先呈現重要功能的 SLI、錯誤、延遲、處理量與飽和度,再提供組成項目與單次操作的深入查詢。
圖表至少要能按照環境、部署單位與版本篩選,並標記部署、設定或相依項目變更時間。比較變更前後時要使用相同時間範圍與統計方式,不能只憑兩張縮放比例不同的圖表判斷改善或退化。
儀表板適合呈現需要持續觀察但沒有立即動作的趨勢。必須由人員在指定時間內處理的狀態才適合告警。
告警條件應該對應使用對象能感受到的問題、即將超過的限制,或已確認需要人工介入的故障。每項告警至少要包含:
operationId 與處理手冊入口。短暫波動可以使用持續時間避免立即觸發。Prometheus 的告警規則提供 for 條件,讓狀態持續指定時間後才進入觸發。實際時間仍要按照問題影響與可接受偵測時間決定。
無法採取任何動作的通知只會增加雜訊。每次事件處理後,應該檢查告警是否過早、過晚、重複,或缺少必要脈絡,再調整門檻、合併方式與處理說明。
記錄、指標與追蹤的資料量、查詢方式與敏感程度不同,應該分別設定:
監控資料本身也需要監控。收集延遲、資料缺口、查詢失敗或告警通知失敗都可能讓問題無法被發現,應該有獨立的檢查與替代通知方式。
設定完成後,要用受控情境確認從問題發生到採取動作的完整流程:
演練不能只確認通知有送出。最終還要驗證功能與資料結果已恢復,並且告警會在恢復條件成立後結束。部署方式、版本、重要功能或相依項目改變時,也要重新執行相關情境。