fix(tracing): Fix unsampled/deferred trace propagation in span streaming#6757
fix(tracing): Fix unsampled/deferred trace propagation in span streaming#6757sentrivana wants to merge 20 commits into
Conversation
Codecov Results 📊✅ 90225 passed | ⏭️ 6302 skipped | Total: 96527 | Pass Rate: 93.47% | Execution Time: 308m 11s 📊 Comparison with Base Branch
All tests are passing successfully. ✅ Patch coverage is 97.14%. Project has 2436 uncovered lines. Files with missing lines (1)
Coverage diff@@ Coverage Diff @@
## main #PR +/-##
==========================================
+ Coverage 89.74% 89.78% +0.04%
==========================================
Files 192 192 —
Lines 23823 23833 +10
Branches 8226 8232 +6
==========================================
+ Hits 21378 21397 +19
- Misses 2445 2436 -9
- Partials 1349 1349 —Generated by Codecov Action |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Want reviews to match your repository better? Bugbot Learning can learn team-specific rules from PR activity. A team admin can enable Learning in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 46b410a. Configure here.
|
Converting to draft to address bot comments |

Description
The SDK didn't behave correctly in some trace propagation scenarios in stream mode.
The current SDK design was emitting headers with a deferred sampling decision if the sampling decision was negative (whether inherited or not), because it was falling back to TwP (tracing without performance) behavior too eagerly.
How it should work
In the following, tracing enabled means either a
traces_sample_rateor atraces_sampleris defined. Tracing disabled means both areNoneand tracing without performance is active.There are three kinds of sampling decisions: sampled (
1), unsampled (0), and deferred (``), meaning no decision.The problem and the fix
If a no-op span was active, we were falling back to the propagation context to generate propagation headers, which by default doesn't contain a sampling decision.
With this PR,
NoOpStreamedSpansnow carry their own trace and span ID information as well as the current propagation data (a snapshot of the propagation context, likeStreamedSpans) and use it to emit the correct headers. This mirrors old behavior: spans would always be created, whether they'd be sampled or not, and they would be responsible for generating propagation headers; with the fallback to the propagation context only kicking in if there is no span.Issues
Closes #6755
Reminders
uv run ruff.feat:,fix:,ref:,meta:)