Skip to content

Update vertexai instrumentation to use Logs API instead of the deprecated events API #3626

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -111,17 +111,15 @@ 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()
)
method_wrappers = MethodWrappers(tracer, logger, is_content_enabled())
for client_class, method_name, wrapper in _methods_to_wrap(
method_wrappers
):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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
"""
Expand All @@ -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,
},
Expand All @@ -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
"""
Expand All @@ -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,
},
Expand All @@ -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
"""
Expand All @@ -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,
},
Expand All @@ -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
"""
Expand All @@ -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,
},
Expand Down Expand Up @@ -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
"""
Expand All @@ -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,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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")
Expand All @@ -95,17 +93,15 @@ def vertexai_init(vcr: VCR) -> None:


@pytest.fixture
def instrument_no_content(
tracer_provider, event_logger_provider, meter_provider
):
def instrument_no_content(tracer_provider, logger_provider, meter_provider):
os.environ.update(
{OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT: "False"}
)

instrumentor = VertexAIInstrumentor()
instrumentor.instrument(
tracer_provider=tracer_provider,
event_logger_provider=event_logger_provider,
logger_provider=logger_provider,
meter_provider=meter_provider,
)

Expand All @@ -116,16 +112,14 @@ def instrument_no_content(


@pytest.fixture
def instrument_with_content(
tracer_provider, event_logger_provider, meter_provider
):
def instrument_with_content(tracer_provider, logger_provider, meter_provider):
os.environ.update(
{OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT: "True"}
)
instrumentor = VertexAIInstrumentor()
instrumentor.instrument(
tracer_provider=tracer_provider,
event_logger_provider=event_logger_provider,
logger_provider=logger_provider,
meter_provider=meter_provider,
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Loading