Skip to content

Commit 7befc7d

Browse files
.
1 parent 4f871a4 commit 7befc7d

3 files changed

Lines changed: 56 additions & 21 deletions

File tree

sentry_sdk/client.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -245,9 +245,15 @@ def _serialized_v1_span_to_serialized_v2_span(
245245

246246
res["attributes"] = {}
247247
for key, value in attributes.items():
248-
res["attributes"][key] = _serialized_v1_attribute_to_serialized_v2_attribute(
249-
value
250-
)
248+
converted_value = _serialized_v1_attribute_to_serialized_v2_attribute(value)
249+
if converted_value is None:
250+
continue
251+
252+
res["attributes"][key] = converted_value
253+
254+
# Remove redundant attribute, as status is stored in the status field.
255+
if "status" in res["attributes"]:
256+
del res["attributes"]["status"]
251257

252258
return res
253259

@@ -268,6 +274,10 @@ def _split_gen_ai_spans(
268274
non_gen_ai_spans = []
269275
gen_ai_spans = []
270276
for span in spans:
277+
if not isinstance(span, dict):
278+
non_gen_ai_spans.append(span)
279+
continue
280+
271281
span_op = span.get("op")
272282
if isinstance(span_op, str) and span_op.startswith("gen_ai."):
273283
gen_ai_spans.append(span)

tests/tracing/test_decorator.py

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,9 @@ async def _some_function_traced(a, b, c):
121121
)
122122

123123

124-
def test_span_templates_ai_dicts(sentry_init, capture_events):
124+
def test_span_templates_ai_dicts(sentry_init, capture_items):
125125
sentry_init(traces_sample_rate=1.0)
126-
events = capture_events()
126+
items = capture_items("span")
127127

128128
@sentry_sdk.trace(template=SPANTEMPLATE.AI_TOOL)
129129
def my_tool(arg1, arg2):
@@ -166,40 +166,57 @@ def my_agent():
166166
with sentry_sdk.start_transaction(name="test-transaction"):
167167
my_agent()
168168

169-
(event,) = events
170-
(agent_span, tool_span, chat_span) = event["spans"]
169+
(agent_span, tool_span, chat_span) = (
170+
item.payload for item in items if item.type == "span"
171+
)
171172

172-
assert agent_span["op"] == "gen_ai.invoke_agent"
173+
assert agent_span["attributes"]["sentry.op"] == "gen_ai.invoke_agent"
173174
assert (
174-
agent_span["description"]
175+
agent_span["name"]
175176
== "invoke_agent test_decorator.test_span_templates_ai_dicts.<locals>.my_agent"
176177
)
177-
assert agent_span["data"] == {
178+
assert agent_span["attributes"] == {
178179
"gen_ai.agent.name": "test_decorator.test_span_templates_ai_dicts.<locals>.my_agent",
179180
"gen_ai.operation.name": "invoke_agent",
181+
"sentry.environment": "production",
182+
"sentry.op": "gen_ai.invoke_agent",
183+
"sentry.origin": "manual",
184+
"sentry.release": mock.ANY,
185+
"sentry.sdk.name": "sentry.python",
186+
"sentry.sdk.version": mock.ANY,
187+
"sentry.segment.id": mock.ANY,
188+
"sentry.segment.name": "test-transaction",
180189
"thread.id": mock.ANY,
181190
"thread.name": mock.ANY,
182191
}
183192

184-
assert tool_span["op"] == "gen_ai.execute_tool"
193+
assert tool_span["attributes"]["sentry.op"] == "gen_ai.execute_tool"
185194
assert (
186-
tool_span["description"]
195+
tool_span["name"]
187196
== "execute_tool test_decorator.test_span_templates_ai_dicts.<locals>.my_tool"
188197
)
189-
assert tool_span["data"] == {
198+
assert tool_span["attributes"] == {
190199
"gen_ai.tool.name": "test_decorator.test_span_templates_ai_dicts.<locals>.my_tool",
191200
"gen_ai.operation.name": "execute_tool",
192201
"gen_ai.usage.input_tokens": 10,
193202
"gen_ai.usage.output_tokens": 20,
194203
"gen_ai.usage.total_tokens": 30,
204+
"sentry.environment": "production",
205+
"sentry.op": "gen_ai.execute_tool",
206+
"sentry.origin": "manual",
207+
"sentry.release": mock.ANY,
208+
"sentry.sdk.name": "sentry.python",
209+
"sentry.sdk.version": mock.ANY,
210+
"sentry.segment.id": mock.ANY,
211+
"sentry.segment.name": "test-transaction",
195212
"thread.id": mock.ANY,
196213
"thread.name": mock.ANY,
197214
}
198-
assert "gen_ai.tool.description" not in tool_span["data"]
215+
assert "gen_ai.tool.description" not in tool_span["attributes"]
199216

200-
assert chat_span["op"] == "gen_ai.chat"
201-
assert chat_span["description"] == "chat my-gpt-4o-mini"
202-
assert chat_span["data"] == {
217+
assert chat_span["attributes"]["sentry.op"] == "gen_ai.chat"
218+
assert chat_span["name"] == "chat my-gpt-4o-mini"
219+
assert chat_span["attributes"] == {
203220
"gen_ai.operation.name": "chat",
204221
"gen_ai.request.frequency_penalty": 1.0,
205222
"gen_ai.request.max_tokens": 100,
@@ -213,6 +230,14 @@ def my_agent():
213230
"gen_ai.usage.input_tokens": 11,
214231
"gen_ai.usage.output_tokens": 22,
215232
"gen_ai.usage.total_tokens": 33,
233+
"sentry.environment": "production",
234+
"sentry.op": "gen_ai.chat",
235+
"sentry.origin": "manual",
236+
"sentry.release": mock.ANY,
237+
"sentry.sdk.name": "sentry.python",
238+
"sentry.sdk.version": mock.ANY,
239+
"sentry.segment.id": mock.ANY,
240+
"sentry.segment.name": "test-transaction",
216241
"thread.id": mock.ANY,
217242
"thread.name": mock.ANY,
218243
}

tests/tracing/test_misc.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -611,11 +611,11 @@ class TestConversationIdPropagation:
611611
"""Tests for conversation_id propagation to AI spans."""
612612

613613
def test_conversation_id_propagates_to_span_with_gen_ai_operation_name(
614-
self, sentry_init, capture_events
614+
self, sentry_init, capture_items
615615
):
616616
"""Span with gen_ai.operation.name data should get conversation_id."""
617617
sentry_init(traces_sample_rate=1.0)
618-
events = capture_events()
618+
items = capture_items("span")
619619

620620
scope = sentry_sdk.get_current_scope()
621621
scope.set_conversation_id("conv-op-name-test")
@@ -624,8 +624,8 @@ def test_conversation_id_propagates_to_span_with_gen_ai_operation_name(
624624
with start_span(op="http.client") as span:
625625
span.set_data("gen_ai.operation.name", "chat")
626626

627-
(event,) = events
628-
span_data = event["spans"][0]["data"]
627+
spans = [item.payload for item in items if item.type == "span"]
628+
span_data = spans[0]["data"]
629629
assert span_data.get("gen_ai.conversation.id") == "conv-op-name-test"
630630

631631
def test_conversation_id_propagates_to_span_with_ai_op(

0 commit comments

Comments
 (0)