From 275a48f222534dc5d283e56bde8578918913a59f Mon Sep 17 00:00:00 2001 From: Dylan Russell Date: Mon, 23 Jun 2025 18:35:55 +0000 Subject: [PATCH 1/8] Initial commit removing events from vertex ai instrumentation --- .../instrumentation/vertexai/__init__.py | 10 +++--- .../instrumentation/vertexai/events.py | 32 +++++++++---------- .../instrumentation/vertexai/patch.py | 10 +++--- .../instrumentation/vertexai/utils.py | 6 ++-- .../tests/conftest.py | 16 ++++------ 5 files changed, 36 insertions(+), 38 deletions(-) diff --git a/instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/__init__.py b/instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/__init__.py index f9fa082014..4afd6182c1 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/__init__.py +++ b/instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/__init__.py @@ -47,7 +47,7 @@ wrap_function_wrapper, # type: ignore[reportUnknownVariableType] ) -from opentelemetry._events import get_event_logger +from opentelemetry._logs import get_logger from opentelemetry.instrumentation.instrumentor import BaseInstrumentor from opentelemetry.instrumentation.utils import unwrap from opentelemetry.instrumentation.vertexai.package import _instruments @@ -111,16 +111,16 @@ def _instrument(self, **kwargs: Any): tracer_provider, schema_url=Schemas.V1_28_0.value, ) - event_logger_provider = kwargs.get("event_logger_provider") - event_logger = get_event_logger( + logger_provider = kwargs.get("logger_provider") + logger = get_logger( __name__, "", schema_url=Schemas.V1_28_0.value, - event_logger_provider=event_logger_provider, + logger_provider=logger_provider, ) method_wrappers = MethodWrappers( - tracer, event_logger, is_content_enabled() + tracer, logger, is_content_enabled() ) for client_class, method_name, wrapper in _methods_to_wrap( method_wrappers diff --git a/instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/events.py b/instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/events.py index 2b7a9369a8..46e4957e42 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/events.py +++ b/instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/events.py @@ -25,7 +25,7 @@ from dataclasses import asdict, dataclass from typing import Any, Iterable, Literal -from opentelemetry._events import Event +from opentelemetry._logs import LogRecord from opentelemetry.semconv._incubating.attributes import gen_ai_attributes from opentelemetry.util.types import AnyValue @@ -34,7 +34,7 @@ def user_event( *, role: str = "user", content: AnyValue = None, -) -> Event: +) -> LogRecord: """Creates a User event https://github.com/open-telemetry/semantic-conventions/blob/v1.28.0/docs/gen-ai/gen-ai-events.md#user-event """ @@ -43,8 +43,8 @@ def user_event( } if content is not None: body["content"] = content - return Event( - name="gen_ai.user.message", + return LogRecord( + event_name="gen_ai.user.message", attributes={ gen_ai_attributes.GEN_AI_SYSTEM: gen_ai_attributes.GenAiSystemValues.VERTEX_AI.value, }, @@ -56,7 +56,7 @@ def assistant_event( *, role: str = "assistant", content: AnyValue = None, -) -> Event: +) -> LogRecord: """Creates an Assistant event https://github.com/open-telemetry/semantic-conventions/blob/v1.28.0/docs/gen-ai/gen-ai-events.md#assistant-event """ @@ -65,8 +65,8 @@ def assistant_event( } if content is not None: body["content"] = content - return Event( - name="gen_ai.assistant.message", + return LogRecord( + event_name="gen_ai.assistant.message", attributes={ gen_ai_attributes.GEN_AI_SYSTEM: gen_ai_attributes.GenAiSystemValues.VERTEX_AI.value, }, @@ -78,7 +78,7 @@ def system_event( *, role: str = "system", content: AnyValue = None, -) -> Event: +) -> LogRecord: """Creates a System event https://github.com/open-telemetry/semantic-conventions/blob/v1.28.0/docs/gen-ai/gen-ai-events.md#system-event """ @@ -87,8 +87,8 @@ def system_event( } if content is not None: body["content"] = content - return Event( - name="gen_ai.system.message", + return LogRecord( + event_name="gen_ai.system.message", attributes={ gen_ai_attributes.GEN_AI_SYSTEM: gen_ai_attributes.GenAiSystemValues.VERTEX_AI.value, }, @@ -101,7 +101,7 @@ def tool_event( role: str | None, id_: str, content: AnyValue = None, -) -> Event: +) -> LogRecord: """Creates a Tool message event https://github.com/open-telemetry/semantic-conventions/blob/v1.28.0/docs/gen-ai/gen-ai-events.md#event-gen_aitoolmessage """ @@ -114,8 +114,8 @@ def tool_event( } if content is not None: body["content"] = content - return Event( - name="gen_ai.tool.message", + return LogRecord( + event_name="gen_ai.tool.message", attributes={ gen_ai_attributes.GEN_AI_SYSTEM: gen_ai_attributes.GenAiSystemValues.VERTEX_AI.value, }, @@ -156,7 +156,7 @@ def choice_event( index: int, message: ChoiceMessage, tool_calls: Iterable[ChoiceToolCall] = (), -) -> Event: +) -> LogRecord: """Creates a choice event, which describes the Gen AI response message. https://github.com/open-telemetry/semantic-conventions/blob/v1.28.0/docs/gen-ai/gen-ai-events.md#event-gen_aichoice """ @@ -172,8 +172,8 @@ def choice_event( if tool_calls_list: body["tool_calls"] = tool_calls_list - return Event( - name="gen_ai.choice", + return LogRecord( + event_name="gen_ai.choice", attributes={ gen_ai_attributes.GEN_AI_SYSTEM: gen_ai_attributes.GenAiSystemValues.VERTEX_AI.value, }, diff --git a/instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/patch.py b/instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/patch.py index 2d24c5d9ad..451fa31db6 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/patch.py +++ b/instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/patch.py @@ -23,7 +23,7 @@ MutableSequence, ) -from opentelemetry._events import EventLogger +from opentelemetry._logs import Logger from opentelemetry.instrumentation.vertexai.utils import ( GenerateContentParams, get_genai_request_attributes, @@ -91,10 +91,10 @@ def _extract_params( class MethodWrappers: def __init__( - self, tracer: Tracer, event_logger: EventLogger, capture_content: bool + self, tracer: Tracer, logger: Logger, capture_content: bool ) -> None: self.tracer = tracer - self.event_logger = event_logger + self.logger = logger self.capture_content = capture_content @contextmanager @@ -122,7 +122,7 @@ def _with_instrumentation( for event in request_to_events( params=params, capture_content=self.capture_content ): - self.event_logger.emit(event) + self.logger.emit(event) # TODO: set error.type attribute # https://github.com/open-telemetry/semantic-conventions/blob/main/docs/gen-ai/gen-ai-spans.md @@ -143,7 +143,7 @@ def handle_response( for event in response_to_events( response=response, capture_content=self.capture_content ): - self.event_logger.emit(event) + self.logger.emit(event) yield handle_response diff --git a/instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/utils.py b/instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/utils.py index b92dfc79eb..a3bcd109f2 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/utils.py +++ b/instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/utils.py @@ -28,7 +28,7 @@ from google.protobuf import json_format -from opentelemetry._events import Event +from opentelemetry._logs import LogRecord from opentelemetry.instrumentation.vertexai.events import ( ChoiceMessage, ChoiceToolCall, @@ -204,7 +204,7 @@ def get_span_name(span_attributes: Mapping[str, AttributeValue]) -> str: def request_to_events( *, params: GenerateContentParams, capture_content: bool -) -> Iterable[Event]: +) -> Iterable[LogRecord]: # System message if params.system_instruction: request_content = _parts_to_any_value( @@ -261,7 +261,7 @@ def response_to_events( response: prediction_service.GenerateContentResponse | prediction_service_v1beta1.GenerateContentResponse, capture_content: bool, -) -> Iterable[Event]: +) -> Iterable[LogRecord]: for candidate in response.candidates: tool_calls = _extract_tool_calls( candidate=candidate, capture_content=capture_content diff --git a/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/conftest.py b/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/conftest.py index fb0956f0b5..f9a8367878 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/conftest.py +++ b/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/conftest.py @@ -17,7 +17,6 @@ from opentelemetry.instrumentation.vertexai.utils import ( OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT, ) -from opentelemetry.sdk._events import EventLoggerProvider from opentelemetry.sdk._logs import LoggerProvider from opentelemetry.sdk._logs.export import ( InMemoryLogExporter, @@ -63,13 +62,12 @@ def fixture_tracer_provider(span_exporter): return provider -@pytest.fixture(scope="function", name="event_logger_provider") -def fixture_event_logger_provider(log_exporter): +@pytest.fixture(scope="function", name="logger_provider") +def fixture_logger_provider(log_exporter): provider = LoggerProvider() provider.add_log_record_processor(SimpleLogRecordProcessor(log_exporter)) - event_logger_provider = EventLoggerProvider(provider) - return event_logger_provider + return provider @pytest.fixture(scope="function", name="meter_provider") @@ -96,7 +94,7 @@ def vertexai_init(vcr: VCR) -> None: @pytest.fixture def instrument_no_content( - tracer_provider, event_logger_provider, meter_provider + tracer_provider, logger_provider, meter_provider ): os.environ.update( {OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT: "False"} @@ -105,7 +103,7 @@ def instrument_no_content( instrumentor = VertexAIInstrumentor() instrumentor.instrument( tracer_provider=tracer_provider, - event_logger_provider=event_logger_provider, + logger_provider=logger_provider, meter_provider=meter_provider, ) @@ -117,7 +115,7 @@ def instrument_no_content( @pytest.fixture def instrument_with_content( - tracer_provider, event_logger_provider, meter_provider + tracer_provider, logger_provider, meter_provider ): os.environ.update( {OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT: "True"} @@ -125,7 +123,7 @@ def instrument_with_content( instrumentor = VertexAIInstrumentor() instrumentor.instrument( tracer_provider=tracer_provider, - event_logger_provider=event_logger_provider, + logger_provider=logger_provider, meter_provider=meter_provider, ) From fb6181e067e0c11aaf4fcebc080163bfd4c7dfa2 Mon Sep 17 00:00:00 2001 From: Dylan Russell Date: Wed, 9 Jul 2025 19:54:03 +0000 Subject: [PATCH 2/8] Fix broken tests --- .../instrumentation/vertexai/__init__.py | 4 +- .../tests/conftest.py | 8 +- .../tests/test_chat_completions.py | 60 +++++-------- .../tests/test_function_calling.py | 85 +++++++------------ 4 files changed, 52 insertions(+), 105 deletions(-) diff --git a/instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/__init__.py b/instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/__init__.py index 4afd6182c1..96d96645aa 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/__init__.py +++ b/instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/__init__.py @@ -119,9 +119,7 @@ def _instrument(self, **kwargs: Any): logger_provider=logger_provider, ) - method_wrappers = MethodWrappers( - tracer, logger, is_content_enabled() - ) + method_wrappers = MethodWrappers(tracer, logger, is_content_enabled()) for client_class, method_name, wrapper in _methods_to_wrap( method_wrappers ): diff --git a/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/conftest.py b/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/conftest.py index f9a8367878..4be52a1bd7 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/conftest.py +++ b/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/conftest.py @@ -93,9 +93,7 @@ def vertexai_init(vcr: VCR) -> None: @pytest.fixture -def instrument_no_content( - tracer_provider, logger_provider, meter_provider -): +def instrument_no_content(tracer_provider, logger_provider, meter_provider): os.environ.update( {OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT: "False"} ) @@ -114,9 +112,7 @@ def instrument_no_content( @pytest.fixture -def instrument_with_content( - tracer_provider, logger_provider, meter_provider -): +def instrument_with_content(tracer_provider, logger_provider, meter_provider): os.environ.update( {OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT: "True"} ) diff --git a/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/test_chat_completions.py b/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/test_chat_completions.py index 0b80bcb745..90ffb4741f 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/test_chat_completions.py +++ b/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/test_chat_completions.py @@ -78,10 +78,8 @@ def test_generate_content( assert user_log.trace_id == span_context.trace_id assert user_log.span_id == span_context.span_id assert user_log.trace_flags == span_context.trace_flags - assert user_log.attributes == { - "gen_ai.system": "vertex_ai", - "event.name": "gen_ai.user.message", - } + assert user_log.attributes == {"gen_ai.system": "vertex_ai"} + assert user_log.event_name == "gen_ai.user.message" assert user_log.body == { "content": [{"text": "Say this is a test"}], "role": "user", @@ -90,10 +88,8 @@ def test_generate_content( assert choice_log.trace_id == span_context.trace_id assert choice_log.span_id == span_context.span_id assert choice_log.trace_flags == span_context.trace_flags - assert choice_log.attributes == { - "gen_ai.system": "vertex_ai", - "event.name": "gen_ai.choice", - } + assert choice_log.attributes == {"gen_ai.system": "vertex_ai"} + assert choice_log.event_name == "gen_ai.choice" assert choice_log.body == { "finish_reason": "stop", "index": 0, @@ -143,16 +139,12 @@ def test_generate_content_without_events( logs = log_exporter.get_finished_logs() assert len(logs) == 2 user_log, choice_log = [log_data.log_record for log_data in logs] - assert user_log.attributes == { - "gen_ai.system": "vertex_ai", - "event.name": "gen_ai.user.message", - } + assert user_log.attributes == {"gen_ai.system": "vertex_ai"} + assert user_log.event_name == "gen_ai.user.message" assert user_log.body == {"role": "user"} - assert choice_log.attributes == { - "gen_ai.system": "vertex_ai", - "event.name": "gen_ai.choice", - } + assert choice_log.attributes == {"gen_ai.system": "vertex_ai"} + assert choice_log.event_name == "gen_ai.choice" assert choice_log.body == { "finish_reason": "stop", "index": 0, @@ -285,10 +277,8 @@ def test_generate_content_invalid_role( # Emits the faulty content which caused the request to fail logs = log_exporter.get_finished_logs() assert len(logs) == 1 - assert logs[0].log_record.attributes == { - "gen_ai.system": "vertex_ai", - "event.name": "gen_ai.user.message", - } + assert logs[0].log_record.attributes == {"gen_ai.system": "vertex_ai"} + assert logs[0].log_record.event_name == "gen_ai.user.message" assert logs[0].log_record.body == { "content": [{"text": "Say this is a test"}], "role": "invalid_role", @@ -418,47 +408,37 @@ def generate_content_all_input_events( log_data.log_record for log_data in logs ] - assert system_log.attributes == { - "gen_ai.system": "vertex_ai", - "event.name": "gen_ai.system.message", - } + assert system_log.attributes == {"gen_ai.system": "vertex_ai"} + assert system_log.event_name == "gen_ai.system.message" assert system_log.body == { "content": [{"text": "You are a clever language model"}], # The API only allows user and model, so system instruction is considered a user role "role": "user", } - assert user_log1.attributes == { - "gen_ai.system": "vertex_ai", - "event.name": "gen_ai.user.message", - } + assert user_log1.attributes == {"gen_ai.system": "vertex_ai"} + assert user_log1.event_name == "gen_ai.user.message" assert user_log1.body == { "content": [{"text": "My name is OpenTelemetry"}], "role": "user", } - assert assistant_log.attributes == { - "gen_ai.system": "vertex_ai", - "event.name": "gen_ai.assistant.message", - } + assert assistant_log.attributes == {"gen_ai.system": "vertex_ai"} + assert assistant_log.event_name == "gen_ai.assistant.message" assert assistant_log.body == { "content": [{"text": "Hello OpenTelemetry!"}], "role": "model", } - assert user_log2.attributes == { - "gen_ai.system": "vertex_ai", - "event.name": "gen_ai.user.message", - } + assert user_log2.attributes == {"gen_ai.system": "vertex_ai"} + assert user_log2.event_name == "gen_ai.user.message" assert user_log2.body == { "content": [{"text": "Address me by name and say this is a test"}], "role": "user", } - assert choice_log.attributes == { - "gen_ai.system": "vertex_ai", - "event.name": "gen_ai.choice", - } + assert choice_log.attributes == {"gen_ai.system": "vertex_ai"} + assert choice_log.event_name == "gen_ai.choice" assert choice_log.body == { "finish_reason": "stop", "index": 0, diff --git a/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/test_function_calling.py b/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/test_function_calling.py index cb8b6ab0df..489b287e7b 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/test_function_calling.py +++ b/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/test_function_calling.py @@ -44,10 +44,8 @@ def test_function_call_choice( logs = log_exporter.get_finished_logs() assert len(logs) == 2 user_log, choice_log = [log_data.log_record for log_data in logs] - assert user_log.attributes == { - "gen_ai.system": "vertex_ai", - "event.name": "gen_ai.user.message", - } + assert user_log.attributes == {"gen_ai.system": "vertex_ai"} + assert user_log.event_name == "gen_ai.user.message" assert user_log.body == { "content": [ {"text": "Get weather details in New Delhi and San Francisco?"} @@ -55,10 +53,8 @@ def test_function_call_choice( "role": "user", } - assert choice_log.attributes == { - "gen_ai.system": "vertex_ai", - "event.name": "gen_ai.choice", - } + assert choice_log.attributes == {"gen_ai.system": "vertex_ai"} + assert choice_log.event_name == "gen_ai.choice" assert choice_log.body == { "finish_reason": "stop", "index": 0, @@ -111,18 +107,14 @@ def test_function_call_choice_no_content( logs = log_exporter.get_finished_logs() assert len(logs) == 2 user_log, choice_log = [log_data.log_record for log_data in logs] - assert user_log.attributes == { - "gen_ai.system": "vertex_ai", - "event.name": "gen_ai.user.message", - } + assert user_log.attributes == {"gen_ai.system": "vertex_ai"} + assert user_log.event_name == "gen_ai.user.message" assert user_log.body == { "role": "user", } - assert choice_log.attributes == { - "gen_ai.system": "vertex_ai", - "event.name": "gen_ai.choice", - } + assert choice_log.attributes == {"gen_ai.system": "vertex_ai"} + assert choice_log.event_name == "gen_ai.choice" assert choice_log.body == { "finish_reason": "stop", "index": 0, @@ -172,10 +164,8 @@ def test_tool_events( user_log, assistant_log, tool_log1, tool_log2, choice_log = [ log_data.log_record for log_data in logs ] - assert user_log.attributes == { - "gen_ai.system": "vertex_ai", - "event.name": "gen_ai.user.message", - } + assert user_log.attributes == {"gen_ai.system": "vertex_ai"} + assert user_log.event_name == "gen_ai.user.message" assert user_log.body == { "content": [ {"text": "Get weather details in New Delhi and San Francisco?"} @@ -183,10 +173,8 @@ def test_tool_events( "role": "user", } - assert assistant_log.attributes == { - "gen_ai.system": "vertex_ai", - "event.name": "gen_ai.assistant.message", - } + assert assistant_log.attributes == {"gen_ai.system": "vertex_ai"} + assert assistant_log.event_name == "gen_ai.assistant.message" assert assistant_log.body == { "role": "model", "content": [ @@ -205,10 +193,8 @@ def test_tool_events( ], } - assert tool_log1.attributes == { - "gen_ai.system": "vertex_ai", - "event.name": "gen_ai.tool.message", - } + assert tool_log1.attributes == {"gen_ai.system": "vertex_ai"} + assert tool_log1.event_name == "gen_ai.tool.message" assert tool_log1.body == { "role": "user", @@ -216,20 +202,16 @@ def test_tool_events( "content": {"content": '{"temperature": 35, "unit": "C"}'}, } - assert tool_log2.attributes == { - "gen_ai.system": "vertex_ai", - "event.name": "gen_ai.tool.message", - } + assert tool_log2.attributes == {"gen_ai.system": "vertex_ai"} + assert tool_log2.event_name == "gen_ai.tool.message" assert tool_log2.body == { "role": "user", "id": "get_current_weather_1", "content": {"content": '{"temperature": 25, "unit": "C"}'}, } - assert choice_log.attributes == { - "gen_ai.system": "vertex_ai", - "event.name": "gen_ai.choice", - } + assert choice_log.attributes == {"gen_ai.system": "vertex_ai"} + assert choice_log.event_name == "gen_ai.choice" assert choice_log.body == { "finish_reason": "stop", "index": 0, @@ -274,34 +256,25 @@ def test_tool_events_no_content( user_log, assistant_log, tool_log1, tool_log2, choice_log = [ log_data.log_record for log_data in logs ] - assert user_log.attributes == { - "gen_ai.system": "vertex_ai", - "event.name": "gen_ai.user.message", - } + assert user_log.attributes == {"gen_ai.system": "vertex_ai"} + assert user_log.event_name == "gen_ai.user.message" assert user_log.body == {"role": "user"} - assert assistant_log.attributes == { - "gen_ai.system": "vertex_ai", - "event.name": "gen_ai.assistant.message", - } + assert assistant_log.attributes == {"gen_ai.system": "vertex_ai"} + assert assistant_log.event_name == "gen_ai.assistant.message" assert assistant_log.body == {"role": "model"} - assert tool_log1.attributes == { - "gen_ai.system": "vertex_ai", - "event.name": "gen_ai.tool.message", - } + assert tool_log1.attributes == {"gen_ai.system": "vertex_ai"} + assert tool_log1.event_name == "gen_ai.tool.message" + assert tool_log1.body == {"role": "user", "id": "get_current_weather_0"} - assert tool_log2.attributes == { - "gen_ai.system": "vertex_ai", - "event.name": "gen_ai.tool.message", - } + assert tool_log2.attributes == {"gen_ai.system": "vertex_ai"} + assert tool_log2.event_name == "gen_ai.tool.message" assert tool_log2.body == {"role": "user", "id": "get_current_weather_1"} - assert choice_log.attributes == { - "gen_ai.system": "vertex_ai", - "event.name": "gen_ai.choice", - } + assert choice_log.attributes == {"gen_ai.system": "vertex_ai"} + assert choice_log.event_name == "gen_ai.choice" assert choice_log.body == { "finish_reason": "stop", "index": 0, From 5bc6f8d853132bbaa9803c66cc9a91c31aaec41e Mon Sep 17 00:00:00 2001 From: Dylan Russell Date: Wed, 9 Jul 2025 19:56:49 +0000 Subject: [PATCH 3/8] Add changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c1f37cf4d..3a482610ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `opentelemetry-resource-detector-containerid`: make it more quiet on platforms without cgroups ([#3579](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3579)) +- `opentelemetry-instrumentation-vertexai`: migrate off the deprecated events API to use the logs API + ([#3625](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3626)) ### Added From 1d3b768f54d85afe487ad38b89bbdba48a59de89 Mon Sep 17 00:00:00 2001 From: Dylan Russell Date: Fri, 11 Jul 2025 14:26:52 +0000 Subject: [PATCH 4/8] Update changelog --- CHANGELOG.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 22e94a804c..e0154d07df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Added + +### Fixed + +- `opentelemetry-instrumentation-vertexai`: migrate off the deprecated events API to use the logs API + ([#3625](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3626)) + ## Version 1.35.0/0.56b0 (2025-07-11) ### Added @@ -30,8 +37,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#3567](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3567)) - `opentelemetry-resource-detector-containerid`: make it more quiet on platforms without cgroups ([#3579](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3579)) -- `opentelemetry-instrumentation-vertexai`: migrate off the deprecated events API to use the logs API - ([#3625](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3626)) ## Version 1.34.0/0.55b0 (2025-06-04) From ce207b61aa1beeb7784d49766dbd5eddd4b38bab Mon Sep 17 00:00:00 2001 From: Dylan Russell Date: Fri, 11 Jul 2025 14:32:12 +0000 Subject: [PATCH 5/8] Update oldest dependencies and pyproject.toml --- .../opentelemetry-instrumentation-vertexai/pyproject.toml | 6 +++--- .../tests/requirements.oldest.txt | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/instrumentation-genai/opentelemetry-instrumentation-vertexai/pyproject.toml b/instrumentation-genai/opentelemetry-instrumentation-vertexai/pyproject.toml index 692a338a69..522e90d4ac 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-vertexai/pyproject.toml +++ b/instrumentation-genai/opentelemetry-instrumentation-vertexai/pyproject.toml @@ -24,9 +24,9 @@ classifiers = [ "Programming Language :: Python :: 3.12", ] dependencies = [ - "opentelemetry-api ~= 1.28", - "opentelemetry-instrumentation ~= 0.49b0", - "opentelemetry-semantic-conventions ~= 0.49b0", + "opentelemetry-api >= 1.35.0", + "opentelemetry-instrumentation ~= 0.56b0", + "opentelemetry-semantic-conventions ~= 0.56b0", ] [project.optional-dependencies] diff --git a/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/requirements.oldest.txt b/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/requirements.oldest.txt index 304a5698c7..cdd6f06b31 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/requirements.oldest.txt +++ b/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/requirements.oldest.txt @@ -66,9 +66,9 @@ yarl==1.15.2 zipp==3.20.2 # when updating, also update in pyproject.toml -opentelemetry-api==1.28 -opentelemetry-sdk==1.28 -opentelemetry-semantic-conventions==0.49b0 -opentelemetry-instrumentation==0.49b0 +opentelemetry-api==1.35.0 +opentelemetry-sdk==1.35.0 +opentelemetry-semantic-conventions==0.56b0 +opentelemetry-instrumentation==0.56b0 -e instrumentation-genai/opentelemetry-instrumentation-vertexai[instruments] From 1c7cb2c7bc45d4ee8866471ca9fb616a79c5972a Mon Sep 17 00:00:00 2001 From: Dylan Russell Date: Tue, 16 Sep 2025 20:47:57 +0000 Subject: [PATCH 6/8] Update dependencies --- .../opentelemetry-instrumentation-vertexai/pyproject.toml | 6 +++--- .../tests/requirements.oldest.txt | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/instrumentation-genai/opentelemetry-instrumentation-vertexai/pyproject.toml b/instrumentation-genai/opentelemetry-instrumentation-vertexai/pyproject.toml index 522e90d4ac..9a16726d55 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-vertexai/pyproject.toml +++ b/instrumentation-genai/opentelemetry-instrumentation-vertexai/pyproject.toml @@ -24,9 +24,9 @@ classifiers = [ "Programming Language :: Python :: 3.12", ] dependencies = [ - "opentelemetry-api >= 1.35.0", - "opentelemetry-instrumentation ~= 0.56b0", - "opentelemetry-semantic-conventions ~= 0.56b0", + "opentelemetry-api >= 1.37.0", + "opentelemetry-instrumentation ~= 0.58b0", + "opentelemetry-semantic-conventions ~= 0.58b0", ] [project.optional-dependencies] diff --git a/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/requirements.oldest.txt b/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/requirements.oldest.txt index cdd6f06b31..28b8175e92 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/requirements.oldest.txt +++ b/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/requirements.oldest.txt @@ -66,9 +66,9 @@ yarl==1.15.2 zipp==3.20.2 # when updating, also update in pyproject.toml -opentelemetry-api==1.35.0 -opentelemetry-sdk==1.35.0 -opentelemetry-semantic-conventions==0.56b0 -opentelemetry-instrumentation==0.56b0 +opentelemetry-api==1.37.0 +opentelemetry-sdk==1.37.0 +opentelemetry-semantic-conventions==0.58b0 +opentelemetry-instrumentation==0.58b0 -e instrumentation-genai/opentelemetry-instrumentation-vertexai[instruments] From 14deddc1aa993591fe9e9f2dae672e90be35e40d Mon Sep 17 00:00:00 2001 From: Dylan Russell Date: Fri, 3 Oct 2025 19:03:30 +0000 Subject: [PATCH 7/8] Fix broken tests --- .../src/opentelemetry/instrumentation/vertexai/patch.py | 2 +- .../tests/test_chat_completions.py | 2 +- .../tests/test_function_calling.py | 9 ++++----- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/patch.py b/instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/patch.py index a4beb5171e..e11ea6e8b6 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/patch.py +++ b/instrumentation-genai/opentelemetry-instrumentation-vertexai/src/opentelemetry/instrumentation/vertexai/patch.py @@ -228,7 +228,7 @@ def handle_response( } ) event = LogRecord( - name="gen_ai.client.inference.operation.details", + event_name="gen_ai.client.inference.operation.details", ) event.attributes = attributes if capture_content in ( diff --git a/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/test_chat_completions.py b/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/test_chat_completions.py index 029b11c273..61bbc0775a 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/test_chat_completions.py +++ b/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/test_chat_completions.py @@ -267,8 +267,8 @@ def test_generate_content_invalid_role( log = logs[0].log_record assert log.attributes == { "gen_ai.system": "vertex_ai", - "event.name": "gen_ai.user.message", } + assert log.event_name == "gen_ai.user.message" assert log.body == { "content": [{"text": "Say this is a test"}], "role": "invalid_role", diff --git a/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/test_function_calling.py b/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/test_function_calling.py index ee4c790364..88762d6100 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/test_function_calling.py +++ b/instrumentation-genai/opentelemetry-instrumentation-vertexai/tests/test_function_calling.py @@ -265,22 +265,21 @@ def test_tool_events_no_content( assert tool_log1.attributes == { "gen_ai.system": "vertex_ai", - "event.name": "gen_ai.tool.message", } + assert tool_log1.event_name == "gen_ai.tool.message" assert tool_log1.body == { "role": "user", "id": "get_current_weather_0", } assert tool_log1.event_name == "gen_ai.tool.message" - assert tool_log2.attributes == { - "gen_ai.system": "vertex_ai", - "event.name": "gen_ai.tool.message", - } + assert tool_log2.attributes == {"gen_ai.system": "vertex_ai"} + assert tool_log2.body == { "role": "user", "id": "get_current_weather_1", } + assert tool_log2.event_name == "gen_ai.tool.message" assert choice_log.attributes == {"gen_ai.system": "vertex_ai"} assert choice_log.event_name == "gen_ai.choice" From 1b239afcc87f2f57cddeef4528d328dec84cd35b Mon Sep 17 00:00:00 2001 From: Dylan Russell Date: Mon, 6 Oct 2025 14:19:59 +0000 Subject: [PATCH 8/8] Respond to comments --- CHANGELOG.md | 1 - .../opentelemetry-instrumentation-vertexai/pyproject.toml | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8091dbb1c3..95d22a4600 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `opentelemetry-instrumentation-dbapi`: fix crash retrieving libpq version when enabling commenter with psycopg ([#3796](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3796)) - - `opentelemetry-instrumentation-vertexai`: migrate off the deprecated events API to use the logs API ([#3625](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3626)) diff --git a/instrumentation-genai/opentelemetry-instrumentation-vertexai/pyproject.toml b/instrumentation-genai/opentelemetry-instrumentation-vertexai/pyproject.toml index 21af75e041..ae7ee29073 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-vertexai/pyproject.toml +++ b/instrumentation-genai/opentelemetry-instrumentation-vertexai/pyproject.toml @@ -24,7 +24,7 @@ classifiers = [ "Programming Language :: Python :: 3.12", ] dependencies = [ - "opentelemetry-api >= 1.37.0", + "opentelemetry-api >= 1.37", "opentelemetry-instrumentation ~= 0.58b0", # TODO https://github.com/open-telemetry/opentelemetry-python-contrib/issues/3786: restrict # version after the first release