Workers tracing — new startActiveSpan() and span.end() runtime APIs
Cloudflare Workers now provides startActiveSpan() and span.end() APIs for writing custom spans that remain open after the callback returns, enabling instrumentation of asynchronous operations like stream pipelines that span multiple callbacks.
The Workers runtime now provides built-in tracing.startActiveSpan() and span.end() APIs, allowing you to write custom spans for operations that last beyond a single callback — for example, instrumenting a stream pipeline where the span should stay open until the stream is fully consumed.
This augments the existing API for writing custom spans, tracing.enterSpan(), which automatically ends a span when its callback is returned. With startActiveSpan(), the span remains open after the callback returns, and you call span.end() when the work is complete:
import { tracing } from "cloudflare:workers";
const encoder = new TextEncoder();
export default {
fetch() {
return tracing.startActiveSpan("stream-response", (span) => {
let timer;
const body = new ReadableStream({
start(controller) {
controller.enqueue(encoder.encode("Starting...\n"));
timer = setTimeout(() => {
controller.enqueue(encoder.encode("Complete.\n"));
controller.close();
span.setAttribute("stream.status", "complete");
span.end();
}, 1000);
},
cancel() {
if (timer !== undefined) clearTimeout(timer);
span.setAttribute("stream.status", "cancelled");
span.end();
},
});
return new Response(body, {
headers: { "content-type": "text/plain" },
});
});
},
};src/index.tstsimport { tracing } from "cloudflare:workers";
const encoder = new TextEncoder();
export default {
fetch(): Response {
return tracing.startActiveSpan("stream-response", (span) => {
let timer: ReturnType<typeof setTimeout> | undefined;
const body = new ReadableStream<Uint8Array>({
start(controller) {
controller.enqueue(encoder.encode("Starting...\n"));
timer = setTimeout(() => {
controller.enqueue(encoder.encode("Complete.\n"));
controller.close();
span.setAttribute("stream.status", "complete");
span.end();
}, 1000);
},
cancel() {
if (timer !== undefined) clearTimeout(timer);
span.setAttribute("stream.status", "cancelled");
span.end();
},
});
return new Response(body, {
headers: { "content-type": "text/plain" },
});
});
},
};
For more details, refer to the custom spans documentation.
Source: original entry ↗