From 3d1ebe17cd2b835e271e2c2749fa56570a6cfe22 Mon Sep 17 00:00:00 2001 From: Ivana Kellyer Date: Mon, 27 Apr 2026 12:48:21 +0200 Subject: [PATCH] feat(argv): Support span streaming --- sentry_sdk/traces.py | 9 ++++ tests/tracing/test_span_streaming.py | 63 ++++++++++++++++++++++------ 2 files changed, 60 insertions(+), 12 deletions(-) diff --git a/sentry_sdk/traces.py b/sentry_sdk/traces.py index 485be2a3e2..221695b679 100644 --- a/sentry_sdk/traces.py +++ b/sentry_sdk/traces.py @@ -7,6 +7,7 @@ sentry_sdk.init(_experiments={"trace_lifecycle": "stream"}). """ +import sys import uuid import warnings from datetime import datetime, timedelta, timezone @@ -294,6 +295,8 @@ def __init__( self._start_profile() self._set_profile_id(get_profiler_id()) + self._set_segment_attributes() + self._start() def __repr__(self) -> str: @@ -552,6 +555,12 @@ def _start_profile(self) -> None: self._continuous_profile = try_profile_lifecycle_trace_start() + def _set_segment_attributes(self) -> None: + if not self._is_segment(): + return + + self.set_attribute("process.command_args", sys.argv) + class NoOpStreamedSpan(StreamedSpan): __slots__ = ( diff --git a/tests/tracing/test_span_streaming.py b/tests/tracing/test_span_streaming.py index 8859aa39c3..849c0a5fb5 100644 --- a/tests/tracing/test_span_streaming.py +++ b/tests/tracing/test_span_streaming.py @@ -1504,6 +1504,46 @@ def test_profile_stops_when_segment_ends( assert get_profiler_id() is None, "profiler should have stopped" +def test_default_attributes(sentry_init, capture_envelopes): + sentry_init( + server_name="test-server", + release="1.0.0", + traces_sample_rate=1.0, + _experiments={"trace_lifecycle": "stream"}, + ) + + envelopes = capture_envelopes() + + with sentry_sdk.traces.start_span(name="test"): + ... + + sentry_sdk.get_client().flush() + + assert len(envelopes) == 1 + assert len(envelopes[0].items) == 1 + item = envelopes[0].items[0] + + assert item.type == "span" + assert item.headers == { + "type": "span", + "item_count": 1, + "content_type": "application/vnd.sentry.items.span.v2+json", + } + assert item.payload.json["items"][0]["attributes"] == { + "thread.id": {"value": mock.ANY, "type": "string"}, + "thread.name": {"value": "MainThread", "type": "string"}, + "process.command_args": {"value": mock.ANY, "type": "array"}, + "sentry.segment.id": {"value": mock.ANY, "type": "string"}, + "sentry.segment.name": {"value": "test", "type": "string"}, + "sentry.sdk.name": {"value": "sentry.python", "type": "string"}, + "sentry.sdk.version": {"value": mock.ANY, "type": "string"}, + "server.address": {"value": "test-server", "type": "string"}, + "sentry.environment": {"value": "production", "type": "string"}, + "sentry.release": {"value": "1.0.0", "type": "string"}, + "sentry.origin": {"value": "manual", "type": "string"}, + } + + def test_transport_format(sentry_init, capture_envelopes): sentry_init( server_name="test-server", @@ -1539,18 +1579,17 @@ def test_transport_format(sentry_init, capture_envelopes): "is_segment": True, "start_timestamp": mock.ANY, "end_timestamp": mock.ANY, - "attributes": { - "thread.id": {"value": mock.ANY, "type": "string"}, - "thread.name": {"value": "MainThread", "type": "string"}, - "sentry.segment.id": {"value": mock.ANY, "type": "string"}, - "sentry.segment.name": {"value": "test", "type": "string"}, - "sentry.sdk.name": {"value": "sentry.python", "type": "string"}, - "sentry.sdk.version": {"value": mock.ANY, "type": "string"}, - "server.address": {"value": "test-server", "type": "string"}, - "sentry.environment": {"value": "production", "type": "string"}, - "sentry.release": {"value": "1.0.0", "type": "string"}, - "sentry.origin": {"value": "manual", "type": "string"}, - }, + "attributes": mock.ANY, } ] } + for attribute, value in item.payload.json["items"][0]["attributes"].items(): + assert isinstance(attribute, str) + + assert isinstance(value, dict) + assert ( + len(value) == 2 + ) # technically, "unit" is also supported, but we don't currently set it anywhere + assert "value" in value + assert "type" in value + assert value["type"] in ("string", "boolean", "integer", "double", "array")