1818
1919from opentelemetry import trace
2020from opentelemetry ._events import Event
21+ from opentelemetry ._logs import LogRecord
2122from opentelemetry .context import Context , get_current
2223from opentelemetry .metrics import Meter
2324from opentelemetry .semconv ._incubating .attributes import (
@@ -59,20 +60,19 @@ def _get_property_value(obj, property_name) -> object:
5960 return getattr (obj , property_name , None )
6061
6162
62- def _message_to_event (message , system , framework ) -> Optional [Event ]:
63- # TODO: Convert to logs.
63+ def _message_to_event (message , provider_name , framework ) -> Optional [Event ]:
6464 content = _get_property_value (message , "content" )
65+ # TODO: check if content is not None and should_collect_content()
6566 if content :
6667 # update this to event.gen_ai.client.inference.operation.details: https://github.com/open-telemetry/semantic-conventions/blob/main/docs/gen-ai/gen-ai-events.md
67-
6868 message_type = _get_property_value (message , "type" )
6969 message_type = "user" if message_type == "human" else message_type
7070 body = {"content" : content }
7171 attributes = {
7272 # TODO: add below to opentelemetry.semconv._incubating.attributes.gen_ai_attributes
73- "gen_ai.provider.name" : system , # Added in 1.37 - https://github.com/open-telemetry/semantic-conventions/blob/main/docs/registry/attributes/gen-ai.md#gen-ai-provider-name
73+ "gen_ai.provider.name" : provider_name , # Added in 1.37 - https://github.com/open-telemetry/semantic-conventions/blob/main/docs/registry/attributes/gen-ai.md#gen-ai-provider-name
7474 "gen_ai.framework" : framework ,
75- GenAI .GEN_AI_SYSTEM : system , # Deprecated: Removed in 1.37
75+ GenAI .GEN_AI_SYSTEM : provider_name , # Deprecated: Removed in 1.37
7676 }
7777
7878 return Event (
@@ -82,16 +82,37 @@ def _message_to_event(message, system, framework) -> Optional[Event]:
8282 )
8383
8484
85+ def _message_to_log_record (
86+ message , provider_name , framework
87+ ) -> Optional [LogRecord ]:
88+ content = _get_property_value (message , "content" )
89+ # check if content is not None and should_collect_content()
90+ message_type = _get_property_value (message , "type" )
91+ body = {"content" : content }
92+
93+ attributes = {
94+ # TODO: add below to opentelemetry.semconv._incubating.attributes.gen_ai_attributes
95+ "gen_ai.framework" : framework ,
96+ "gen_ai.provider.name" : provider_name ,
97+ GenAI .GEN_AI_SYSTEM : provider_name , # Deprecated: use "gen_ai.provider.name"
98+ }
99+
100+ return LogRecord (
101+ event_name = f"gen_ai.{ message_type } .message" ,
102+ attributes = attributes ,
103+ body = body or None ,
104+ )
105+
106+
85107def _chat_generation_to_event (
86- chat_generation , index , system , framework
108+ chat_generation , index , provider_name , framework
87109) -> Optional [Event ]:
88- # TODO: Convert to logs.
89110 if chat_generation .content :
90111 attributes = {
91112 # TODO: add below to opentelemetry.semconv._incubating.attributes.gen_ai_attributes
92- "gen_ai.provider.name" : system , # added in 1.37 - https://github.com/open-telemetry/semantic-conventions/blob/main/docs/registry/attributes/gen-ai.md#gen-ai-provider-name
113+ "gen_ai.provider.name" : provider_name , # added in 1.37 - https://github.com/open-telemetry/semantic-conventions/blob/main/docs/registry/attributes/gen-ai.md#gen-ai-provider-name
93114 "gen_ai.framework" : framework ,
94- GenAI .GEN_AI_SYSTEM : system , # Deprecated: removed in 1.37
115+ GenAI .GEN_AI_SYSTEM : provider_name , # Deprecated: removed in 1.37
95116 }
96117
97118 message = {
@@ -111,6 +132,34 @@ def _chat_generation_to_event(
111132 )
112133
113134
135+ def _chat_generation_to_log_record (
136+ chat_generation , index , prefix , provider_name , framework
137+ ) -> Optional [LogRecord ]:
138+ if chat_generation :
139+ attributes = {
140+ # TODO: add below to opentelemetry.semconv._incubating.attributes.gen_ai_attributes
141+ "gen_ai.framework" : framework ,
142+ "gen_ai.provider.name" : provider_name ,
143+ GenAI .GEN_AI_SYSTEM : provider_name , # Deprecated: removed in 1.37
144+ }
145+
146+ message = {
147+ "content" : chat_generation .content ,
148+ "type" : chat_generation .type ,
149+ }
150+ body = {
151+ "index" : index ,
152+ "finish_reason" : chat_generation .finish_reason or "error" ,
153+ "message" : message ,
154+ }
155+
156+ return LogRecord (
157+ event_name = "gen_ai.choice" ,
158+ attributes = attributes ,
159+ body = body or None ,
160+ )
161+
162+
114163def _get_metric_attributes (
115164 request_model : Optional [str ],
116165 response_model : Optional [str ],
@@ -204,7 +253,7 @@ def init(self, invocation: LLMInvocation):
204253 self ._event_logger .emit (
205254 _message_to_event (
206255 message = message ,
207- system = system ,
256+ provider_name = system ,
208257 framework = invocation .attributes .get ("framework" ),
209258 )
210259 )
0 commit comments