Skip to content

Commit d24dd3f

Browse files
committed
Rename chat spans with resolved models
1 parent 29fb58f commit d24dd3f

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed

instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/src/opentelemetry/instrumentation/openai_agents/span_processor.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1426,6 +1426,25 @@ def on_span_end(self, span: Span[Any]) -> None:
14261426
otel_span.set_attribute(key, value)
14271427
attributes[key] = value
14281428

1429+
if _is_instance_of(
1430+
span.span_data, (GenerationSpanData, ResponseSpanData)
1431+
):
1432+
operation_name = attributes.get(GEN_AI_OPERATION_NAME)
1433+
model_for_name = attributes.get(GEN_AI_REQUEST_MODEL) or (
1434+
attributes.get(GEN_AI_RESPONSE_MODEL)
1435+
)
1436+
if operation_name and model_for_name:
1437+
agent_name_for_name = attributes.get(GEN_AI_AGENT_NAME)
1438+
tool_name_for_name = attributes.get(GEN_AI_TOOL_NAME)
1439+
new_name = get_span_name(
1440+
operation_name,
1441+
model_for_name,
1442+
agent_name_for_name,
1443+
tool_name_for_name,
1444+
)
1445+
if new_name != otel_span.name:
1446+
otel_span.update_name(new_name)
1447+
14291448
# Emit span events for captured content when configured
14301449
self._emit_content_events(span, otel_span, payload, agent_content)
14311450

instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/tests/test_z_span_processor_unit.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -499,3 +499,47 @@ def test_span_lifecycle_and_shutdown(processor_setup):
499499
statuses["linger"].status_code is StatusCode.ERROR
500500
and statuses["linger"].description == "Application shutdown"
501501
)
502+
503+
504+
def test_chat_span_renamed_with_model(processor_setup):
505+
processor, exporter = processor_setup
506+
507+
trace = FakeTrace(name="workflow", trace_id="trace-rename")
508+
processor.on_trace_start(trace)
509+
510+
agent = FakeSpan(
511+
trace_id=trace.trace_id,
512+
span_id="agent-span",
513+
span_data=AgentSpanData(
514+
operation="invoke_agent",
515+
name="Agent",
516+
),
517+
started_at="2025-01-01T00:00:00Z",
518+
ended_at="2025-01-01T00:00:02Z",
519+
)
520+
processor.on_span_start(agent)
521+
522+
generation_data = GenerationSpanData(
523+
input=[{"role": "user", "content": "question"}],
524+
output=[{"finish_reason": "stop"}],
525+
usage={"prompt_tokens": 1, "completion_tokens": 1},
526+
)
527+
generation_span = FakeSpan(
528+
trace_id=trace.trace_id,
529+
span_id="child-span",
530+
parent_id=agent.span_id,
531+
span_data=generation_data,
532+
started_at="2025-01-01T00:00:00Z",
533+
ended_at="2025-01-01T00:00:01Z",
534+
)
535+
processor.on_span_start(generation_span)
536+
537+
# Model becomes available before span end (e.g., once response arrives)
538+
generation_data.model = "gpt-4o"
539+
540+
processor.on_span_end(generation_span)
541+
processor.on_span_end(agent)
542+
processor.on_trace_end(trace)
543+
544+
span_names = {span.name for span in exporter.get_finished_spans()}
545+
assert "chat gpt-4o" in span_names

0 commit comments

Comments
 (0)