應用遙測實用指南
應用遙測是軟體生成的結構化證據,包括髮生的事情、針對誰、花費了多長時間以及結果是否有用。良好的遙測技術可以讓產品、工程、支援和運營從同一事件契約中回答問題,而不是從無限制的文字中重建現實。
本指南展示瞭如何選擇正確的訊號、設計安全結果事件、交付它們、使用 SQL 驗證它們,以及將它們轉變為儀表板和警示。
有用的應用程式事件透過儲存和 SQL 分析從發出邊界保持結構化。
應用遙測包括哪些內容
日誌、指標、追蹤和結構化事件重疊,但每個都有一個有用的重心:
| 訊號 | 最擅長 | 典型問題 |
|---|---|---|
| 結構化事件 | 持久的業務或應用程式成果 | 哪些帳戶註冊後無法啟用? |
| 事件寫入 | 詳細的診斷記錄 | 此過程在一次失敗時報告了什麼? |
| 公制 | 廉價總體趨勢 | 請求量或 CPU 是否發生變化? |
| 蹤跡 | 分散式工作的因果路徑 | 哪個跨度使該請求變慢? |
不要強迫一個訊號取代其他所有訊號。終端 api_request_completed 事件可以儲存錯誤率儀表板所需的路線、帳戶、狀態、持續時間和釋放。追蹤可以解釋哪個依賴項消耗了該持續時間。診斷日誌可以保留經過審查的技術訊息。基礎設施指標可以顯示服務是否受到資源限制。
這些訊號之間的共享識別符號通常比複製其完整有效負載更有價值。
從一個決定開始
儀器應該從一個問題和一個行動開始:
- 問題:發布後大多數帳戶的哪些 API 路由失敗?
- 決策:回滾、禁用功能或調查依賴性。
- 事件:
api_request_completed。 - Grain:一項已完成的請求。
- 維度:路由範本、方法、狀態碼、錯誤類別、發布。
- 測量:延遲(以毫秒為單位)。
- 安全關聯:請求和帳戶識別符號。
如果某個欄位不會被已知的過濾器、組、計算、聯接、調查或策略使用,請將其保留。 “以後可能有用”會產生成本、隱私風險和不穩定的模式,但不能保證有用的答案。
設計一份活動合約
終端請求事件可能如下所示:
{
"event_id": "evt_api_01",
"request_id": "req_2f71",
"account_id": "acct_8f31",
"route": "/v1/query/:id",
"method": "POST",
"status_code": 200,
"latency_ms": 184,
"error_type": null,
"release": "2026.07.3"
}
合約應載明:
| 財產 | 定義 |
|---|---|
| 活動名稱 | 穩定的過去時結果,例如 api_request_completed |
| 穀物 | 正是一行代表的內容 |
| 發射邊界 | 應用程式狀態發生變化後,結果即為最終結果 |
| 業主 | 負責製作人的團隊或服務 |
| 必填欄位 | 每個接受的行必須具有的值 |
| 控制值 | 允許的狀態、類別、方法或版本 |
| 單位 | _ms、_bytes、_usd 或其他顯式字尾 |
| 隱私等級 | 非敏感、假名或需要審查 |
| 保留需求 | 決策需要多長時間的資料 |
使用 /v1/query/:id 等路由範本,而不是將每個識別符號轉換為新維度的原始 URL。使用有界的 error_type,而不是堆疊追蹤。保持數字測量數字和字串型別的穩定識別符號。
在結果邊界處發射
僅在已知結果時才記錄結果。對於 HTTP 請求,通常是在最終狀態和持續時間可用之後:
import telemetry from "telemetry-sh";
telemetry.init("YOUR_API_KEY");
async function recordRequest(context, response, startedAtMs) {
await telemetry.log("api_request_completed", {
event_id: crypto.randomUUID(),
request_id: context.requestId,
account_id: context.accountId,
route: context.routeTemplate,
method: context.method,
status_code: response.status,
latency_ms: Date.now() - startedAtMs,
error_type: response.error
? classifyRequestError(response.error)
: null,
release: process.env.APP_RELEASE ?? "unknown"
});
}
Telemetry 在標準化期間刪除空值,因此成功的行不儲存 error_type。查詢層提供timestamp_utc;客戶端提供的具有該名稱的欄位將被刪除。請參閱 日誌API 瞭解確切的可接受形狀和標準化規則。
不要讓遙測傳輸失敗將已完成的業務成果更改為重複的付款、電子郵件、工作或請求。根據工作流程的風險決定是否緩衝、重試、取樣或丟棄。重試傳遞同一邏輯事件時,重複使用同一 event_id。
選擇關聯識別符號
使用與正在調查的實體匹配的識別符號:
event_id對一個遙測事件進行重複資料刪除;request_id連結一次請求的申請證據;job_id連線生命週期事件和重試嘗試;account_id衡量客戶影響;user_id獲批後支援演員級產品分析;trace_id連結到分散式追蹤。
保持識別符號為假名。電子郵件地址、存取權杖、會話 cookie、提示、文件或完整 URL 不是方便的識別符號;它是敏感的有效負載資料。
控制基數和有效負載大小
基數是欄位產生的不同值的數量。高基數 ID 對於調查和聯接很有用,但預設儀表板組較差。無限制的文字很少是安全的分析維度。
用途:
route: "/v1/query/:id"代替/v1/query/9be1...;error_type: "upstream_timeout"代替異常訊息;- 經批准的提供商模型識別符號,而不是臨時顯示標籤;
release: "2026.07.3"而不是完整的部署清單。
對有界域進行分組。僅在受限調查結果中選擇識別符號。省略請求和回應正文,而不是在攝取後嘗試脫敏每個可能的敏感值。
保持型別和含義穩定
事件靈活性不是傳送混合型別的理由。 latency_ms 不得在 184、"184 ms" 和 "slow" 之間交替。 account_id 不得引用一項服務中的使用者和另一項服務中的組織。
附加可選欄位通常是最安全的演變。重新命名、單位更改、型別更改或新的行粒度需要遷移或新的事件版本。在更改儀表板或警示之前,請遵循 模式演化指南 並按版本衡量現場採用情況。
巢狀物件可以建立有用的名稱空間,但每個點路徑仍然是一個契約。參見 查詢巢狀JSON。
單獨的事件時間和攝取時間
定義業務或應用程式結果發生的時間。延遲的移動客戶端、佇列、離線代理和重試緩衝區可能會晚於該時刻傳送。
對於伺服器生成的線上事件,Telemetry的託管timestamp_utc往往是正確的操作查詢時間。如果您的工作流程需要源事件時間,請傳送單獨命名的時區限定時間戳並記錄遲到對報告的影響。不要將部分當前儲存桶與完整的歷史儲存桶進行比較。
使用時間戳指南 涵蓋 UTC、視窗和遲到資料。
查詢第一個有用的問題
從有界樣本開始:
SELECT
timestamp_utc,
route,
status_code,
latency_ms,
release
FROM api_request_completed
WHERE timestamp_utc >= now() - INTERVAL '1 hour'
ORDER BY timestamp_utc DESC
LIMIT 100;
然後計算數量、錯誤率、受影響的帳戶和尾部延遲:
SELECT
route,
COUNT(*) AS requests,
SUM(CASE WHEN status_code >= 500 THEN 1 ELSE 0 END) AS errors,
COUNT(DISTINCT CASE
WHEN status_code >= 500 THEN account_id
END) AS affected_accounts,
100.0 * SUM(CASE WHEN status_code >= 500 THEN 1 ELSE 0 END)
/ NULLIF(COUNT(*), 0) AS error_rate_pct,
approx_percentile_cont(latency_ms, 0.95) AS p95_latency_ms
FROM api_request_completed
WHERE timestamp_utc >= now() - INTERVAL '24 hours'
GROUP BY route
HAVING COUNT(*) >= 20
ORDER BY affected_accounts DESC, error_rate_pct DESC;
最小量規則可以防止單個安靜故障的排名自動超過繁忙的迴歸。關鍵的小批次工作流程可能需要自己的警示,而不是通用排行榜。
建置決策就緒儀表板
應用程式可靠性儀表板應該讓讀者從檢測轉向範圍和證據:
- 請求或工作流程量;
- 完整時間範圍內的成功率或錯誤率;
- p50 和 p95 潛伏期;
- 受影響的帳戶;
- 按路線、錯誤類別和發布進行細分;
- 包含用於調查的請求 ID 的受限資料表。
註釋單位、時間範圍、分母、最小數量、資料新鮮度和事件契約。在重要的 SQL 旁邊保留合成結果或已知裝置,以便審閱者可以知道查詢打算返回什麼。
使用 API 可靠性儀表板範例 和 API 延遲配方 作為完整的起點。
僅在所有者可以回應時發出警示
警示定義需要查詢、精確分母、完整時間視窗、閾值或基線、最小數量、所屬團隊、執行手冊、首次診斷故障以及丟失資料的行為。
例如:當 p95 延遲超過三個完整儲存桶的路由目標並且觀察到至少 100 個請求時,通知 API 所有者。回應首先比較版本、錯誤類別和受影響的帳戶計數。
監視遙測管道本身。平零可能意味著安靜的應用程式、損壞的生產者、交付失敗或查詢錯誤。 遙測傳送事件架構 和 攝入新鮮度配方 使缺失的證據可見。
保護隱私和安全
收集決策所需的最少證據。發布前:
- 對每個識別符號和自由文字欄位進行分類;
- 刪除機密、憑據、cookie、請求正文、提示和生成的內容;
- 使用假名內部 ID;
- 限制暴露參與者或資源識別符號的調查檢視;
- 根據記錄的運營或產品需求設定保留;
- 測試脫敏和失敗分支,而不僅僅是成功的請求;
- 審查資料管轄權和使用的刪除和存取要求。
驗證整個路徑
生產者單元測試是必要的,但還不夠。驗證:
- 成功、失敗、超時、重試和重複分支;
- 欄位名稱、型別、單位和控制值;
- API驗收及錯誤處理;
- 目標資料表中最近的原始行;
- 與已知夾具的總和 SQL;
- 儀表板的時間視窗和分母;
- 警示的閾值、所有者和缺失資料行為;
- 先前生產者版本的回滾路徑。
按部署後的發布追蹤現場覆蓋範圍和事件量。原始碼中存在的程式碼路徑並不能證明生產正在發出完整的事件。
控制成本而不損失結果
在廣泛推出之前估計數量:
events per day
= requests per day
× events per request
× retained sample fraction
當不使用中間狀態時,優先選擇一個最終結果事件而不是多個冗餘進度事件。僅在保留速率所需的分母后才對大容量成功診斷進行取樣。在政策允許的情況下保留故障和罕見的關鍵結果,但不要使用取樣來替代刪除敏感資料。
將保留期與擁有記錄所有者的最長比較或調查視窗保持一致。在成為永久成本之前,不應將任何人質疑的欄位或事件從計劃中刪除。
應用程式遙測部署清單
- 寫下問題、決定、負責人和預期回應。
- 定義一行的粒度和確切的結果邊界。
- 選擇必填欄位、受控值、單位和安全識別符號。
- 對隱私、基數、保留和數量進行分類。
- 新增代表性的成功、失敗、重試、複製和回滾裝置。
- 儀器交付無需改變業務操作語義。
- 按版本驗證接受的行和必填欄位覆蓋率。
- 根據已知結果測試 SQL。
- 發布儀表板定義、新鮮度和分母。
- 僅當所有者和回應明確時才新增警示。
- 監視遙測管道本身。
- 在第一個保留視窗之後檢視欄位並刪除未使用的資料。
繼續使用 設計事件架構、結構化記錄、事件模式目錄 和 端到端 SaaS 可觀測性示範。