Skip to content

WO-1582 Add tracing getActiveSpan - #7111

Open
jmorrell-cloudflare wants to merge 5 commits into
jmorrell/refactor-spansfrom
jmorrell/add-get-active-span
Open

WO-1582 Add tracing getActiveSpan#7111
jmorrell-cloudflare wants to merge 5 commits into
jmorrell/refactor-spansfrom
jmorrell/add-get-active-span

Conversation

@jmorrell-cloudflare

@jmorrell-cloudflare jmorrell-cloudflare commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Builds on top of #7093

Adds tracing.getActiveSpan()

  • getActiveSpan() returns the active user-created span when one exists.
  • Otherwise, it returns a wrapper for the current invocation span.
  • It returns undefined outside an invocation or in an async context detached from the invocation.
  • Invocation-span wrappers are cached, so repeated calls return the same object.
  • Calling end() on an invocation span is a no-op because the platform owns its lifecycle.

When you create your own spans, you get a reference to a span that you can add attributes to, but there is currently no way of getting a reference to this span if you are never passed it. This is important for middlewares, instrumentation, etc.

Additionally, we've had no way to get a reference to the root invocation span. This is where all of the interesting data lives! Extending the attributes of this invocation span is an o11y best practice (IMO)..

Things like:

  • this request was served on /user/:id
  • this request was served for user 1234
  • these are the active feature flags for this request

We currently have no internal span object that represents this invocation span. This adds InvocationSpanState to fill that role.

This should work exactly as a normal span except that it should treat span.end() as a no-op, since that lifecycle is owned by the platform. There is some precedent for this in the NonRecordingSpan in the otel-sdk.

There were some tricky bits for overlapping Durable Object requests. They share an IoContext: a continuation from request A must not emit attributes through request B’s tracer after B becomes the current request.

@jmorrell-cloudflare
jmorrell-cloudflare requested review from a team as code owners August 25, 2026 00:06
@jmorrell-cloudflare
jmorrell-cloudflare requested review from emily-shen and removed request for a team August 25, 2026 00:06
@jmorrell-cloudflare jmorrell-cloudflare changed the title jmorrell/add get active span WO-1582 Add tracing getActiveSpan Aug 25, 2026
@jmorrell-cloudflare
jmorrell-cloudflare marked this pull request as draft August 25, 2026 00:10
Comment thread src/workerd/api/tracing.c++ Outdated
}

auto& ioContext = IoContext::current();
auto context = ioContext.getInvocationSpanContext();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] Preserve the request that owns a cached invocation span

An async frame from Durable Object request A can resume after request B has been delivered, making B incomingRequests.front() (see IoContext::IncomingRequest::delivered()). The frame still contains A’s user SpanParent, but these values are read from the current IoContext, so the cached wrapper combines A’s parent with B’s tracer and trace/invocation IDs. setAttribute() then emits A’s attribute into B’s tail trace. Store the originating tracer and InvocationSpanContext with the user-trace async-context holder when it is created, and construct the cached InvocationSpanState from that captured origin rather than IoContext::getCurrent*(); add an overlapping-DO-request regression test.

@ask-bonk

ask-bonk Bot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

I'm Bonk, and I've done a quick review of your PR.

Adds tracing.getActiveSpan() and invocation-span attribute support.

  1. P1 src/workerd/api/tracing.c++:457 can attribute resumed Durable Object request A to request B’s trace. Posted inline.

github run

@codecov-commenter

codecov-commenter commented Aug 25, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 27.33813% with 101 lines in your changes missing coverage. Please review.
✅ Project coverage is 67.90%. Comparing base (a2aa06b) to head (f2fc2e0).

Files with missing lines Patch % Lines
src/workerd/api/tracing.c++ 8.53% 75 Missing ⚠️
src/workerd/io/tracer.c++ 0.00% 26 Missing ⚠️
Additional details and impacted files
@@                     Coverage Diff                     @@
##           jmorrell/refactor-spans    #7111      +/-   ##
===========================================================
- Coverage                    67.95%   67.90%   -0.05%     
===========================================================
  Files                          465      465              
  Lines                       130753   130877     +124     
  Branches                     21389    21411      +22     
===========================================================
+ Hits                         88847    88871      +24     
- Misses                       28934    29033      +99     
- Partials                     12972    12973       +1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@jmorrell-cloudflare
jmorrell-cloudflare marked this pull request as ready for review August 25, 2026 01:59
@jmorrell-cloudflare
jmorrell-cloudflare force-pushed the jmorrell/add-get-active-span branch from 165a055 to 73eb9f4 Compare August 25, 2026 02:05
Add an internal WorkerTracer entry point that accepts an explicit
timestamp. This allows process-sandbox tracing to preserve the timestamp
from the sandbox, where the request's IoContext is available.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants