From 15dc263bc063ab4773328f35ca8a014623f90273 Mon Sep 17 00:00:00 2001 From: Jan Michael Auer Date: Fri, 23 May 2025 16:49:04 +0200 Subject: [PATCH] fix(spans): Support `None` and full `uint64` in `span.data` --- .../spans/consumers/process_segments/convert.py | 7 ++++++- .../consumers/process_segments/test_convert.py | 16 +++++++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/sentry/spans/consumers/process_segments/convert.py b/src/sentry/spans/consumers/process_segments/convert.py index da83bdb243d271..ef0330bb8c0eaf 100644 --- a/src/sentry/spans/consumers/process_segments/convert.py +++ b/src/sentry/spans/consumers/process_segments/convert.py @@ -13,6 +13,8 @@ from sentry.spans.consumers.process_segments.types import Span +I64_MAX = 2**63 - 1 + FIELD_TO_ATTRIBUTE = { "description": "sentry.raw_description", "duration_ms": "sentry.duration_ms", @@ -38,7 +40,8 @@ def convert_span_to_item(span: Span) -> TraceItem: server_sample_rate = 1.0 for k, v in (span.get("data") or {}).items(): - attributes[k] = _anyvalue(v) + if v is not None: + attributes[k] = _anyvalue(v) for k, v in (span.get("measurements") or {}).items(): if k is not None and v is not None: @@ -87,6 +90,8 @@ def _anyvalue(value: Any) -> AnyValue: elif isinstance(value, bool): return AnyValue(bool_value=value) elif isinstance(value, int): + if value > I64_MAX: + return AnyValue(double_value=float(value)) return AnyValue(int_value=value) elif isinstance(value, float): return AnyValue(double_value=value) diff --git a/tests/sentry/spans/consumers/process_segments/test_convert.py b/tests/sentry/spans/consumers/process_segments/test_convert.py index 79a026ac7a5e87..1cde6d9ec1f901 100644 --- a/tests/sentry/spans/consumers/process_segments/test_convert.py +++ b/tests/sentry/spans/consumers/process_segments/test_convert.py @@ -2,7 +2,7 @@ from google.protobuf.timestamp_pb2 import Timestamp from sentry_protos.snuba.v1.request_common_pb2 import TraceItemType -from sentry_protos.snuba.v1.trace_item_pb2 import AnyValue +from sentry_protos.snuba.v1.trace_item_pb2 import AnyValue, KeyValue, KeyValueList from sentry.spans.consumers.process_segments.convert import convert_span_to_item from sentry.spans.consumers.process_segments.types import Span @@ -30,6 +30,11 @@ "my.neg.float.field": -101.2, "my.true.bool.field": True, "my.false.bool.field": False, + "my.dict.field": { + "id": 42, + "name": "test", + }, + "my.u64.field": 9447000002305251000, }, "measurements": { "num_of_spans": {"value": 50.0}, @@ -145,4 +150,13 @@ def test_convert_span_to_item(): "relay_use_post_or_schedule_rejected": AnyValue(string_value="version"), "sentry.normalized_description": AnyValue(string_value="normalized_description"), "thread.name": AnyValue(string_value="uWSGIWorker1Core0"), + "my.dict.field": AnyValue( + kvlist_value=KeyValueList( + values=[ + KeyValue(key="id", value=AnyValue(int_value=42)), + KeyValue(key="name", value=AnyValue(string_value="test")), + ] + ) + ), + "my.u64.field": AnyValue(double_value=9447000002305251000.0), }