Skip to content

Commit 30b9d0d

Browse files
committed
Fix opentelemetry compatibility with version<1.35
1 parent 27f1a0d commit 30b9d0d

File tree

6 files changed

+191
-53
lines changed

6 files changed

+191
-53
lines changed

docs/logfire.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ Note that the OpenTelemetry Semantic Conventions are still experimental and are
283283

284284
### Setting OpenTelemetry SDK providers
285285

286-
By default, the global `TracerProvider` and `LoggerProvider` are used. These are set automatically by `logfire.configure()`. They can also be set by the `set_tracer_provider` and `set_event_logger_provider` functions in the OpenTelemetry Python SDK. You can set custom providers with [`InstrumentationSettings`][pydantic_ai.models.instrumented.InstrumentationSettings].
286+
By default, the global `TracerProvider` and `LoggerProvider` are used. These are set automatically by `logfire.configure()`. They can also be set by the `set_tracer_provider` and `set_logger_provider` functions in the OpenTelemetry Python SDK. You can set custom providers with [`InstrumentationSettings`][pydantic_ai.models.instrumented.InstrumentationSettings].
287287

288288
```python {title="instrumentation_settings_providers.py"}
289289
from opentelemetry.sdk._logs import LoggerProvider
@@ -293,7 +293,7 @@ from pydantic_ai.agent import Agent, InstrumentationSettings
293293

294294
instrumentation_settings = InstrumentationSettings(
295295
tracer_provider=TracerProvider(),
296-
event_logger_provider=LoggerProvider(),
296+
logger_provider=LoggerProvider(),
297297
)
298298

299299
agent = Agent('gpt-4o', instrument=instrumentation_settings)

pydantic_ai_slim/pydantic_ai/messages.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ class SystemPromptPart:
7878

7979
def otel_event(self, settings: InstrumentationSettings) -> LogRecord:
8080
return LogRecord(
81-
event_name='gen_ai.system.message',
81+
attributes={'event.name': 'gen_ai.system.message'},
8282
body={'role': 'system', **({'content': self.content} if settings.include_content else {})},
8383
)
8484

@@ -436,7 +436,7 @@ def otel_event(self, settings: InstrumentationSettings) -> LogRecord:
436436
content.append(converted_part)
437437
else:
438438
content.append({'kind': part.kind}) # pragma: no cover
439-
return LogRecord(event_name='gen_ai.user.message', body={'content': content, 'role': 'user'})
439+
return LogRecord(attributes={'event.name': 'gen_ai.user.message'}, body={'content': content, 'role': 'user'})
440440

441441
__repr__ = _utils.dataclasses_no_defaults_repr
442442

@@ -485,7 +485,7 @@ def model_response_object(self) -> dict[str, Any]:
485485

486486
def otel_event(self, settings: InstrumentationSettings) -> LogRecord:
487487
return LogRecord(
488-
event_name='gen_ai.tool.message',
488+
attributes={'event.name': 'gen_ai.tool.message'},
489489
body={
490490
**({'content': self.content} if settings.include_content else {}),
491491
'role': 'tool',
@@ -552,10 +552,13 @@ def model_response(self) -> str:
552552

553553
def otel_event(self, settings: InstrumentationSettings) -> LogRecord:
554554
if self.tool_name is None:
555-
return LogRecord(event_name='gen_ai.user.message', body={'content': self.model_response(), 'role': 'user'})
555+
return LogRecord(
556+
attributes={'event.name': 'gen_ai.user.message'},
557+
body={'content': self.model_response(), 'role': 'user'},
558+
)
556559
else:
557560
return LogRecord(
558-
event_name='gen_ai.tool.message',
561+
attributes={'event.name': 'gen_ai.tool.message'},
559562
body={
560563
**({'content': self.model_response()} if settings.include_content else {}),
561564
'role': 'tool',
@@ -740,7 +743,7 @@ def otel_events(self, settings: InstrumentationSettings) -> list[LogRecord]:
740743

741744
def new_event_body():
742745
new_body: dict[str, Any] = {'role': 'assistant'}
743-
ev = LogRecord(event_name='gen_ai.assistant.message', body=new_body)
746+
ev = LogRecord(attributes={'event.name': 'gen_ai.assistant.message'}, body=new_body)
744747
result.append(ev)
745748
return new_body
746749

pydantic_ai_slim/pydantic_ai/models/instrumented.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ def messages_to_otel_events(self, messages: list[ModelMessage]) -> list[LogRecor
158158
if instructions is not None:
159159
events.append(
160160
LogRecord(
161-
event_name='gen_ai.system.message',
161+
attributes={'event.name': 'gen_ai.system.message'},
162162
body={**({'content': instructions} if self.include_content else {}), 'role': 'system'},
163163
)
164164
)
@@ -303,7 +303,7 @@ def _record_metrics():
303303
for event in self.instrumentation_settings.messages_to_otel_events([response]):
304304
events.append(
305305
LogRecord(
306-
event_name='gen_ai.choice',
306+
attributes={'event.name': 'gen_ai.choice'},
307307
body={
308308
# TODO finish_reason
309309
'index': 0,

tests/models/test_fallback.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ def test_first_failed_instrumented(capfire: CaptureLogfire) -> None:
135135
'gen_ai.usage.input_tokens': 51,
136136
'gen_ai.usage.output_tokens': 1,
137137
'gen_ai.response.model': 'function:success_response:',
138-
'events': '[{"content": "hello", "role": "user", "gen_ai.system": "function", "gen_ai.message.index": 0}, {"index": 0, "message": {"role": "assistant", "content": "success"}, "gen_ai.system": "function"}]',
138+
'events': '[{"content": "hello", "role": "user", "gen_ai.system": "function", "gen_ai.message.index": 0, "event.name": "gen_ai.user.message"}, {"index": 0, "message": {"role": "assistant", "content": "success"}, "gen_ai.system": "function", "event.name": "gen_ai.choice"}]',
139139
'logfire.json_schema': '{"type": "object", "properties": {"events": {"type": "array"}, "model_request_parameters": {"type": "object"}}}',
140140
},
141141
},
@@ -151,7 +151,7 @@ def test_first_failed_instrumented(capfire: CaptureLogfire) -> None:
151151
'logfire.msg': 'agent run',
152152
'logfire.span_type': 'span',
153153
'gen_ai.usage.input_tokens': 51,
154-
'all_messages_events': '[{"content": "hello", "role": "user", "gen_ai.message.index": 0}, {"role": "assistant", "content": "success", "gen_ai.message.index": 1}]',
154+
'all_messages_events': '[{"content": "hello", "role": "user", "gen_ai.message.index": 0, "event.name": "gen_ai.user.message"}, {"role": "assistant", "content": "success", "gen_ai.message.index": 1, "event.name": "gen_ai.assistant.message"}]',
155155
'gen_ai.usage.output_tokens': 1,
156156
'final_result': 'success',
157157
'logfire.json_schema': '{"type": "object", "properties": {"all_messages_events": {"type": "array"}, "final_result": {"type": "object"}}}',
@@ -208,7 +208,7 @@ async def test_first_failed_instrumented_stream(capfire: CaptureLogfire) -> None
208208
'gen_ai.usage.input_tokens': 50,
209209
'gen_ai.usage.output_tokens': 2,
210210
'gen_ai.response.model': 'function::success_response_stream',
211-
'events': '[{"content": "input", "role": "user", "gen_ai.system": "function", "gen_ai.message.index": 0}, {"index": 0, "message": {"role": "assistant", "content": "hello world"}, "gen_ai.system": "function"}]',
211+
'events': '[{"content": "input", "role": "user", "gen_ai.system": "function", "gen_ai.message.index": 0, "event.name": "gen_ai.user.message"}, {"index": 0, "message": {"role": "assistant", "content": "hello world"}, "gen_ai.system": "function", "event.name": "gen_ai.choice"}]',
212212
'logfire.json_schema': '{"type": "object", "properties": {"events": {"type": "array"}, "model_request_parameters": {"type": "object"}}}',
213213
},
214214
},
@@ -225,7 +225,7 @@ async def test_first_failed_instrumented_stream(capfire: CaptureLogfire) -> None
225225
'logfire.span_type': 'span',
226226
'gen_ai.usage.input_tokens': 50,
227227
'gen_ai.usage.output_tokens': 2,
228-
'all_messages_events': '[{"content": "input", "role": "user", "gen_ai.message.index": 0}, {"role": "assistant", "content": "hello world", "gen_ai.message.index": 1}]',
228+
'all_messages_events': '[{"content": "input", "role": "user", "gen_ai.message.index": 0, "event.name": "gen_ai.user.message"}, {"role": "assistant", "content": "hello world", "gen_ai.message.index": 1, "event.name": "gen_ai.assistant.message"}]',
229229
'logfire.json_schema': '{"type": "object", "properties": {"all_messages_events": {"type": "array"}, "final_result": {"type": "object"}}}',
230230
},
231231
},
@@ -303,7 +303,7 @@ def test_all_failed_instrumented(capfire: CaptureLogfire) -> None:
303303
'agent_name': 'agent',
304304
'logfire.msg': 'agent run',
305305
'logfire.span_type': 'span',
306-
'all_messages_events': '[{"content": "hello", "role": "user", "gen_ai.message.index": 0}]',
306+
'all_messages_events': '[{"content": "hello", "role": "user", "gen_ai.message.index": 0, "event.name": "gen_ai.user.message"}]',
307307
'logfire.json_schema': '{"type": "object", "properties": {"all_messages_events": {"type": "array"}, "final_result": {"type": "object"}}}',
308308
'logfire.level_num': 17,
309309
},

0 commit comments

Comments
 (0)