Cloudflare Workers 自訂 span 怎麼用?比較 enterSpan 與 startSpan
Cloudflare Workers 自動建立的 traces 已能呈現平台操作與 RPC 邊界;如果你還想知道某個 handler 裡的「查快取、組資料、呼叫外部服務」各花多久,就要替應用程式的重要步驟加上 custom span。
Cloudflare 在 2026 年 9 月 25 日公告新增 Workers tracing API,包括 getActiveSpan()、recordException()、startSpan() 與 setAttributes()。實作前先選 span 的生命週期:一般函式用 enterSpan(),需要手動結束時再考慮 startActiveSpan() 或 startSpan()。
截至 2026 年 9 月 28 日,Cloudflare 文件仍將 Workers Traces 標示為 Beta;以下內容依當日官方文件整理,正式部署前應再確認 API 狀態與限制。
本文依 Cloudflare Changelog 與 Custom spans 文件整理;沒有部署 Worker 或查詢帳號中的 trace。
開啟 tracing,再標記一段程式
先在 Wrangler 設定中啟用 traces:
{ "observability": { "traces": { "enabled": true } }}接著從 cloudflare:workers 匯入 tracing。下面的 TypeScript 範例把外部請求包成一個 span,同時記錄狀態碼與例外:
import { tracing } from "cloudflare:workers";
async function fetchCatalog() { return tracing.enterSpan("catalog.fetch", async (span) => { span.setAttributes({ "catalog.operation": "fetch", "catalog.source": "primary", });
try { const response = await fetch("https://catalog.example/products"); span.setAttribute("http.response.status_code", response.status); return response; } catch (error) { span.recordException(error as Error); throw error; } });}enterSpan() 會在 callback 執行期間成為目前 active span;裡面的巢狀 spans 和支援 tracing 的平台操作會掛在它底下。callback 回傳、拋出錯誤,或回傳的 Promise settled 後,span 會自動結束,因此一般同步或非同步函式不必自行呼叫 span.end()。
recordException() 只把例外記進 span,不會替你 catch、重新拋出或改變 span 的結束方式。範例仍由程式處理錯誤並保留原本的 throw。
三種建立方式的生命週期
| API | span 何時結束 | 後續操作會成為子 span 嗎? | 適合情境 |
|---|---|---|---|
enterSpan() | callback 結束時自動結束 | callback 內會 | 一般函式與 async 工作 |
startActiveSpan() | 呼叫 span.end() 時 | 只有 callback 執行期間會 | callback 結束後仍要保留 span,例如串流結束前 |
startSpan() | 呼叫 span.end() 時 | 不會;它不會成為 active span | 要獨立計時,但不想讓後續 tracing 操作掛在它底下 |
startActiveSpan() 最容易被誤用:callback 結束後,span 雖然仍開啟,卻已不再是 active parent。此後建立的新 span 不會自動變成它的子 span。若是一般 request 步驟,先用 enterSpan();只有在你清楚控制手動收尾與父子關係時,再改用手動生命週期 API。
共用 helper 若需要替目前操作補上欄位,可以呼叫 tracing.getActiveSpan()?.setAttributes(...)。找不到 active span 時會得到 undefined,所以在沒有 span 的路徑中應安全略過。
Trace 抽樣與錯誤紀錄的界線
啟用 tracing 不代表每個請求都會產生 trace。若請求沒有被抽樣,span.isTraced 會是 false,但 enterSpan() 的 callback 仍會執行;可用它略過昂貴的診斷欄位計算,不要拿它控制應用程式流程。
截至 2026 年 9 月 28 日,Cloudflare Custom spans 文件也列出兩個尚未提供的能力:沒有 spanContext() 可讀取 trace/span ID,也沒有 setStatus()。父子關係由 JavaScript async context 決定,不能手動指定 parent。若你的流程需要跨邊界傳遞 trace ID 或自行改寫父子關係,這套 API 尚不能取代那段需求。
如果你要追的是 Worker 到 Worker 或 Durable Object 的自動 JavaScript RPC spans,請接著看Workers RPC traces 的閱讀順序。那篇處理平台產生的 RPC session 與 invocation;本文處理應用程式自行加入的 spans,兩者可以並用。
參考資料: