mirror of
https://github.com/vercel/workflow.git
synced 2026-09-14 19:59:43 +08:00
2c6ee614b5
* feat(world-vercel): name stream client spans + add stream attributes Stream write/read requests already share the instrumented HTTP envelope (a CLIENT span + W3C trace-context injection), but the spans were named for the bare HTTP verb (`http PUT`/`http GET`) and carried only generic HTTP attributes — so stream latency couldn't be sliced per run/stream. Name these spans for their operation (`workflow.stream.write` / `workflow.stream.read`) and tag them with `workflow.run.id`, `workflow.stream.name`, `workflow.stream.operation` (write | write_multi | close | read), and `workflow.stream.start_index` (read). Implemented via new optional `spanName`/`attributes` fields on `instrumentedFetch`, so other callers are unaffected. Additive OTEL only: no behavior change when no OpenTelemetry SDK is registered (the span is undefined and attributes are dropped). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Shorten changeset summary Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Add client-observed end-to-end read TTFC span The read GET can't report a client-measured latency back to the server (the value only exists after the response starts streaming), so capture it purely in the SDK's own OTEL: watch response.body for the first non-empty chunk and emit a workflow.stream.read span back-dated to read dispatch, whose duration is the end-to-end time-to-first-chunk (incl. the network hop) via workflow.stream.read.ttfc_ms. Rename the fetch/connect span to workflow.stream.read.connect. No-op without an OTEL SDK registered. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Add client-observed e2e write latency attribute The write PUT is request/response and the server acks only after capturing the chunk, so the workflow.stream.write span duration already equals the client->server write latency. Expose it as a named attribute workflow.stream.write.e2e_ms (via a durationAttribute option on instrumentedFetch) for direct querying, parallel to the read ttfc_ms. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs: document stream spans and latency attributes Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Emit read TTFC span from the core reader instead of a world-vercel transform Per review: move the client-observed time-to-first-chunk measurement out of a TransformStream wrapper in world-vercel and into WorkflowServerReadableStream in core, emitting workflow.stream.read on the first non-empty chunk reaching the consumer. Removes the passthrough, measures at the reader abstraction, and is backend-agnostic. world-vercel keeps the workflow.stream.read.connect HTTP span; the recordElapsedSpan helper now lives in @workflow/core. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Apply suggestion from @VaguelySerious Signed-off-by: Peter Wielander <mittgfu@gmail.com> * Update docs/content/docs/v5/observability/tracing.mdx Co-authored-by: Peter Wielander <mittgfu@gmail.com> Signed-off-by: Karthik Kalyan <105607645+karthikscale3@users.noreply.github.com> * Address review: rename write.e2e_ms -> write.chunk_rtt; docs + changeset wording Per review, rename the write attribute to workflow.stream.write.chunk_rtt (it's a per-chunk client<->server round-trip, not a full e2e), update the docs row wording for both write and read attributes, and shorten the changeset. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Signed-off-by: Peter Wielander <mittgfu@gmail.com> Signed-off-by: Karthik Kalyan <105607645+karthikscale3@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Peter Wielander <mittgfu@gmail.com>
98 B
98 B
@workflow/core, @workflow/world-vercel
| @workflow/core | @workflow/world-vercel |
|---|---|
| patch | patch |
Add stream latency to OTEL spans