Skip to content

feat(stdlib): Support span streaming

a3f7747
Select commit
Loading
Failed to load commit list.
Merged

feat(stdlib): Support span streaming #6154

feat(stdlib): Support span streaming
a3f7747
Select commit
Loading
Failed to load commit list.
@sentry/warden / warden completed Apr 28, 2026 in 1m 24s

6 issues

High

Test accesses dict span via attribute syntax, causing AttributeError - `tests/integrations/stdlib/test_httplib.py:245`

After the refactor, request_span is taken from event["spans"][-1], which is a dict (serialized span from the captured event), not a Span object. Accessing request_span.span_id on a dict will raise AttributeError: 'dict' object has no attribute 'span_id', causing the test to fail at runtime. The code should use request_span["span_id"] instead.

Also found at:

  • tests/integrations/stdlib/test_httplib.py:289
request_span.span_id raises AttributeError on serialized span dict - `tests/integrations/stdlib/test_httplib.py:245`

After switching from transaction._span_recorder.spans[-1] (a Span object) to event["spans"][-1] (a serialized dict in the captured event), the code still uses attribute access request_span.span_id. Captured event spans are dictionaries and must be accessed with request_span["span_id"] (as is done elsewhere in the test suite, e.g. tests/integrations/asyncio/test_asyncio.py and tests/integrations/celery/test_celery.py). The test will fail with AttributeError before reaching the assertion.

Also found at:

  • tests/integrations/stdlib/test_httplib.py:289

Medium

Stray debug print statement left in production code - `sentry_sdk/integrations/stdlib.py:162`

A print("span is here") statement was added to the getresponse wrapper. This is clearly leftover debug output that will execute on every HTTP response handled by the stdlib integration, polluting stdout for all users of the SDK and potentially leaking into production logs. This is a behavioral side effect that affects every consumer of the integration.

span_streaming branch in subprocess instrumentation is identical to non-streaming branch, making feature a no-op - `sentry_sdk/integrations/stdlib.py:260-271`

Both arms of if span_streaming: call sentry_sdk.start_span(op=..., name=..., origin=...) with identical arguments. Compare to the httplib instrumentation in the same file (lines 108-126), where the streaming branch invokes sentry_sdk.traces.start_span(name=..., attributes={'sentry.origin': ..., 'sentry.op': ...}) to obtain a StreamedSpan. As written, the type annotation Union[Span, StreamedSpan] is misleading because span will never actually be a StreamedSpan, and span streaming silently does nothing for subprocess spans. Downstream isinstance(span, StreamedSpan) checks (used elsewhere in this file) will never trigger here, so subprocess spans will not be emitted via the streaming pipeline when the feature is enabled.

Low

Identical branches in span_streaming if/else create dead code - `sentry_sdk/integrations/stdlib.py:260-271`

The if span_streaming and else branches at lines 260-271 invoke sentry_sdk.start_span with identical arguments, producing the same result regardless of the span_streaming flag. The span_streaming check therefore has no effect on behavior, suggesting either a missed code path (e.g., a different streaming-specific call was intended) or unnecessary branching. This may indicate incomplete implementation of span streaming support for the subprocess integration.

Leftover debug `print("span is here")` statement in getresponse - `sentry_sdk/integrations/stdlib.py:162`

A debug print("span is here") was left in the patched getresponse function. This will write to stdout on every HTTP response handled by an instrumented HTTPConnection, which constitutes information disclosure into application logs/stdout and adds unbounded noisy output in production. While not a direct security vulnerability, it can leak request flow information and pollute logs at scale.

4 skills analyzed
Skill Findings Duration Cost
code-review 3 43.9s $0.66
find-bugs 3 1m 15s $1.20
skill-scanner 0 14.0s $0.27
security-review 0 14.3s $0.28

Duration: 2m 27s · Tokens: 533.7k in / 8.8k out · Cost: $2.42 (+merge: $0.00, +dedup: $0.00)