fix(tracing): Correctly generate traceparent from NoOpStreamedSpans#6725
fix(tracing): Correctly generate traceparent from NoOpStreamedSpans#6725sentrivana wants to merge 1 commit into
NoOpStreamedSpans#6725Conversation
Codecov Results 📊✅ 90078 passed | ❌ 15 failed | ⏭️ 6298 skipped | Total: 96391 | Pass Rate: 93.45% | Execution Time: 320m 17s 📊 Comparison with Base Branch
➕ New Tests (15)View new tests
❌ Failed Tests
|
There was a problem hiding this comment.
Ignored root-level span still generates a random trace_id instead of inheriting from propagation context (sentry_sdk/scope.py:1301)
The NoOpStreamedSpan returned for an ignored root span (lines 1301–1304) is missing trace_id=propagation_context.trace_id, so it will generate a random trace ID instead of using the one from the propagation context — the same bug this PR fixes for the unsampled case.
Evidence
propagation_contextis fetched at line 1300 before theis_ignored_spancheck.- The unsampled branch at line 1316 was updated by this PR to pass
trace_id=propagation_context.trace_id. - The ignored-span branch at lines 1301–1304 creates
NoOpStreamedSpan(scope=self, unsampled_reason="ignored")with notrace_id. NoOpStreamedSpan.trace_idinheritsStreamedSpan.trace_id, which callsuuid.uuid4().hexwhenself._trace_idis falsy — producing a fresh random ID unrelated to the active trace.- Any outgoing HTTP call made while this span is active will propagate an incorrect
sentry-traceheader.
Existing unsampled-span test still asserts old hardcoded zero trace/span IDs and will now fail (sentry_sdk/traces.py:722)
This PR makes NoOpStreamedSpan trace-aware: Scope._start_streamed_span now constructs the unsampled segment span with trace_id=propagation_context.trace_id (scope.py:1317-1320), and NoOpStreamedSpan inherits trace_id/span_id from StreamedSpan, which returns the propagated trace_id and lazily generates a random span_id (uuid.uuid4().hex[16:]). The existing test test_continue_trace_unsampled in tests/tracing/test_span_streaming.py:747-748 still asserts span.trace_id == "00000000000000000000000000000000" and span.span_id == "0000000000000000". Since that test starts an unsampled segment after continue_trace with trace_id="0af7651916cd43dd8448eb211c80319c", span.trace_id will now be that propagated value and span.span_id will be a random hex, so both assertions will fail. This test file was not updated in the PR (only test_http_headers.py was), so CI will break.
Evidence
- scope.py:1317-1320 now creates the unsampled segment as
NoOpStreamedSpan(scope=self, trace_id=propagation_context.trace_id, unsampled_reason=outcome). NoOpStreamedSpan(traces.py:611) does not overridetrace_id/span_id, so it inheritsStreamedSpan.trace_id(returns_trace_id) andStreamedSpan.span_id(lazyuuid.uuid4().hex[16:]) at traces.py:463-474.test_continue_trace_unsampled(test_span_streaming.py:721) continues a trace withtrace_id="0af7651916cd43dd8448eb211c80319c", sospan.trace_idnow returns that value andspan.span_idreturns random hex — never zeros.- Lines 747-748 still assert the old
"0000..."values, andtest_span_streaming.pyis not in the PR's changed files, so these assertions will fail.
Identified by Warden code-review
Description
When a
NoOpStreamedSpanwas active, I'd report an incorrect traceparent. MakeNoOpStreamedSpans aware of the trace ID and make them generate their own unique span ID.Reminders
uv run ruff.feat:,fix:,ref:,meta:)