diff --git a/CHANGELOG.md b/CHANGELOG.md index 95d22a4600..46ed60e260 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 ([#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)) +- `opentelemetry-instrumentation-google-genai`: migrate off the deprecated events API to use the logs API + ([#3625](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3624)) ### Added - `opentelemetry-instrumentation`: botocore: Add support for AWS Secrets Manager semantic convention attribute @@ -87,6 +89,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#3610](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3610)) - `opentelemetry-instrumentation-system-metrics`: Add `cpython.gc.collections` metrics with collection unit is specified in semconv ([3617](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3617)) +### Added + +### Fixed + + - `opentelemetry-instrumentation-google-genai`: migrate off the deprecated events API to use the logs API + ([#3625](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3624)) + ## Version 1.35.0/0.56b0 (2025-07-11) ### Added diff --git a/instrumentation-genai/opentelemetry-instrumentation-google-genai/pyproject.toml b/instrumentation-genai/opentelemetry-instrumentation-google-genai/pyproject.toml index b3d2bce56b..c14c225978 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-google-genai/pyproject.toml +++ b/instrumentation-genai/opentelemetry-instrumentation-google-genai/pyproject.toml @@ -37,9 +37,9 @@ classifiers = [ "Programming Language :: Python :: 3.12" ] dependencies = [ - "opentelemetry-api >=1.31.1, <2", - "opentelemetry-instrumentation >=0.52b1, <2", - "opentelemetry-semantic-conventions >=0.52b1, <2" + "opentelemetry-api >=1.37, <2", + "opentelemetry-instrumentation >=0.58b0, <2", + "opentelemetry-semantic-conventions >=0.58b0, <2" ] [project.optional-dependencies] diff --git a/instrumentation-genai/opentelemetry-instrumentation-google-genai/src/opentelemetry/instrumentation/google_genai/instrumentor.py b/instrumentation-genai/opentelemetry-instrumentation-google-genai/src/opentelemetry/instrumentation/google_genai/instrumentor.py index 8a3f792651..0c11419c65 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-google-genai/src/opentelemetry/instrumentation/google_genai/instrumentor.py +++ b/instrumentation-genai/opentelemetry-instrumentation-google-genai/src/opentelemetry/instrumentation/google_genai/instrumentor.py @@ -14,7 +14,7 @@ from typing import Any, Collection, Optional -from opentelemetry._events import get_event_logger_provider +from opentelemetry._logs import get_logger_provider from opentelemetry.instrumentation.instrumentor import BaseInstrumentor from opentelemetry.metrics import get_meter_provider from opentelemetry.trace import get_tracer_provider @@ -49,13 +49,13 @@ def _instrument(self, **kwargs: Any): tracer_provider = ( kwargs.get("tracer_provider") or get_tracer_provider() ) - event_logger_provider = ( - kwargs.get("event_logger_provider") or get_event_logger_provider() + logger_provider = ( + kwargs.get("logger_provider") or get_logger_provider() ) meter_provider = kwargs.get("meter_provider") or get_meter_provider() otel_wrapper = OTelWrapper.from_providers( tracer_provider=tracer_provider, - event_logger_provider=event_logger_provider, + logger_provider=logger_provider, meter_provider=meter_provider, ) self._generate_content_snapshot = instrument_generate_content( diff --git a/instrumentation-genai/opentelemetry-instrumentation-google-genai/src/opentelemetry/instrumentation/google_genai/otel_wrapper.py b/instrumentation-genai/opentelemetry-instrumentation-google-genai/src/opentelemetry/instrumentation/google_genai/otel_wrapper.py index b7dbb5de41..b0e354ea1b 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-google-genai/src/opentelemetry/instrumentation/google_genai/otel_wrapper.py +++ b/instrumentation-genai/opentelemetry-instrumentation-google-genai/src/opentelemetry/instrumentation/google_genai/otel_wrapper.py @@ -16,7 +16,7 @@ import google.genai -from opentelemetry._events import Event +from opentelemetry._logs import LogRecord from opentelemetry.semconv._incubating.metrics import gen_ai_metrics from opentelemetry.semconv.schemas import Schemas @@ -36,9 +36,9 @@ class OTelWrapper: - def __init__(self, tracer, event_logger, meter): + def __init__(self, tracer, logger, meter): self._tracer = tracer - self._event_logger = event_logger + self._logger = logger self._meter = meter self._operation_duration_metric = ( gen_ai_metrics.create_gen_ai_client_operation_duration(meter) @@ -48,12 +48,12 @@ def __init__(self, tracer, event_logger, meter): ) @staticmethod - def from_providers(tracer_provider, event_logger_provider, meter_provider): + def from_providers(tracer_provider, logger_provider, meter_provider): return OTelWrapper( tracer_provider.get_tracer( _SCOPE_NAME, _LIBRARY_VERSION, _SCHEMA_URL, _SCOPE_ATTRIBUTES ), - event_logger_provider.get_event_logger( + logger_provider.get_logger( _SCOPE_NAME, _LIBRARY_VERSION, _SCHEMA_URL, _SCOPE_ATTRIBUTES ), meter=meter_provider.get_meter( @@ -88,5 +88,7 @@ def log_response_content(self, attributes, body): self._log_event(event_name, attributes, body) def _log_event(self, event_name, attributes, body): - event = Event(event_name, body=body, attributes=attributes) - self._event_logger.emit(event) + event = LogRecord( + event_name=event_name, body=body, attributes=attributes + ) + self._logger.emit(event) diff --git a/instrumentation-genai/opentelemetry-instrumentation-google-genai/tests/common/otel_mocker.py b/instrumentation-genai/opentelemetry-instrumentation-google-genai/tests/common/otel_mocker.py index fd87d424d9..d3ef52a9c5 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-google-genai/tests/common/otel_mocker.py +++ b/instrumentation-genai/opentelemetry-instrumentation-google-genai/tests/common/otel_mocker.py @@ -13,17 +13,14 @@ # limitations under the License. -import opentelemetry._events import opentelemetry._logs._internal import opentelemetry.metrics._internal import opentelemetry.trace -from opentelemetry._events import ( - get_event_logger_provider, - set_event_logger_provider, +from opentelemetry._logs import ( + get_logger_provider, + set_logger_provider, ) -from opentelemetry._logs import get_logger_provider, set_logger_provider from opentelemetry.metrics import get_meter_provider, set_meter_provider -from opentelemetry.sdk._events import EventLoggerProvider from opentelemetry.sdk._logs import LoggerProvider from opentelemetry.sdk._logs.export import ( InMemoryLogExporter, @@ -43,7 +40,6 @@ def _bypass_otel_once(): opentelemetry.trace._TRACER_PROVIDER_SET_ONCE = Once() opentelemetry._logs._internal._LOGGER_PROVIDER_SET_ONCE = Once() - opentelemetry._events._EVENT_LOGGER_PROVIDER_SET_ONCE = Once() opentelemetry.metrics._internal._METER_PROVIDER_SET_ONCE = Once() @@ -51,14 +47,12 @@ class OTelProviderSnapshot: def __init__(self): self._tracer_provider = get_tracer_provider() self._logger_provider = get_logger_provider() - self._event_logger_provider = get_event_logger_provider() self._meter_provider = get_meter_provider() def restore(self): _bypass_otel_once() set_tracer_provider(self._tracer_provider) set_logger_provider(self._logger_provider) - set_event_logger_provider(self._event_logger_provider) set_meter_provider(self._meter_provider) @@ -82,6 +76,10 @@ def attributes(self): def body(self): return self._log_data.log_record.body + @property + def event_name(self): + return self._log_data.log_record.event_name + def __str__(self): return self._log_data.log_record.to_json() @@ -175,23 +173,21 @@ def assert_does_not_have_span_named(self, name): assert span is None, f"Found unexpected span named {name}" def get_event_named(self, event_name): - for event in self.get_finished_logs(): - event_name_attr = event.attributes.get("event.name") - if event_name_attr is None: - continue - if event_name_attr == event_name: - return event - return None + return next( + ( + event + for event in self.get_finished_logs() + if event.event_name == event_name + ), + None, + ) def get_events_named(self, event_name): - result = [] - for event in self.get_finished_logs(): - event_name_attr = event.attributes.get("event.name") - if event_name_attr is None: - continue - if event_name_attr == event_name: - result.append(event) - return result + return [ + event + for event in self.get_finished_logs() + if event.event_name == event_name + ] def assert_has_event_named(self, name): event = self.get_event_named(name) @@ -219,8 +215,6 @@ def _install_logs(self): provider = LoggerProvider() provider.add_log_record_processor(SimpleLogRecordProcessor(self._logs)) set_logger_provider(provider) - event_provider = EventLoggerProvider(logger_provider=provider) - set_event_logger_provider(event_provider) def _install_metrics(self): provider = MeterProvider(metric_readers=[self._metrics]) diff --git a/instrumentation-genai/opentelemetry-instrumentation-google-genai/tests/requirements.oldest.txt b/instrumentation-genai/opentelemetry-instrumentation-google-genai/tests/requirements.oldest.txt index 50fc45f39f..39a8a44bc2 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-google-genai/tests/requirements.oldest.txt +++ b/instrumentation-genai/opentelemetry-instrumentation-google-genai/tests/requirements.oldest.txt @@ -21,10 +21,10 @@ pytest-vcr==1.0.2 google-auth==2.15.0 google-genai==1.0.0 -opentelemetry-api==1.31.1 -opentelemetry-sdk==1.31.1 -opentelemetry-semantic-conventions==0.52b1 -opentelemetry-instrumentation==0.52b1 +opentelemetry-api==1.37.0 +opentelemetry-sdk==1.37.0 +opentelemetry-semantic-conventions==0.58b0 +opentelemetry-instrumentation==0.58b0 # Install locally from the folder. This path is relative to the # root directory, given invocation from "tox" at root level. diff --git a/instrumentation-genai/opentelemetry-instrumentation-google-genai/tests/utils/test_tool_call_wrapper.py b/instrumentation-genai/opentelemetry-instrumentation-google-genai/tests/utils/test_tool_call_wrapper.py index 3c8aee3f70..2c6b4ea2cb 100644 --- a/instrumentation-genai/opentelemetry-instrumentation-google-genai/tests/utils/test_tool_call_wrapper.py +++ b/instrumentation-genai/opentelemetry-instrumentation-google-genai/tests/utils/test_tool_call_wrapper.py @@ -18,7 +18,7 @@ from google.genai import types as genai_types -from opentelemetry._events import get_event_logger_provider +from opentelemetry._logs import get_logger_provider from opentelemetry.instrumentation.google_genai import ( otel_wrapper, tool_call_wrapper, @@ -35,7 +35,7 @@ def setUp(self): self._otel.install() self._otel_wrapper = otel_wrapper.OTelWrapper.from_providers( get_tracer_provider(), - get_event_logger_provider(), + get_logger_provider(), get_meter_provider(), )