Skip to content
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
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add instrumentation for InteractionsResource.create and AsyncInteractionsResource.create.
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,11 @@ Check out the `manual example <examples/manual>`_ for more details.
Instrumenting all clients
*************************

When using the instrumentor, all clients will automatically trace GenAI ``generate_content`` operations.

When using the instrumentor, all clients will automatically trace GenAI ``generate_content`` operations and ``interactions.create`` operations.
You can also optionally capture prompts and responses as log events.

Make sure to configure OpenTelemetry tracing, logging, metrics, and events to capture all telemetry emitted by the instrumentation.
Make sure to configure OpenTelemetry tracing, logging, and metrics to capture all telemetry emitted by the instrumentation.

.. code-block:: python

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,19 +62,31 @@ def add(a: int, b: int) -> int:

def main():
GoogleGenAiSdkInstrumentor().instrument()
# set vertex ai to False to get the interactions API.
client = genai.Client(
vertexai=True,
# vertexai=False,
project=os.environ["PROJECT_ID"],
location=os.environ["LOCATION"],
)

response = client.models.generate_content(
model=os.environ["MODEL"],
contents=os.environ["PROMPT"],
config=types.GenerateContentConfig(tools=[add]),
)
write_spans_to_file("test_span")
write_logs_to_file("test_log")
print(response.text)
# Example interactions API call..
# response = client.interactions.create(
# model=os.environ["MODEL"],
# input={
# "type": "text",
# "text": "What is the current weather in Tokyo?",
# },
# tools=[{"type": "google_search"}],
# )

write_spans_to_file("span_google_search")
write_logs_to_file("log_google_search")
print(response)


if __name__ == "__main__":
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@ OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT = "SPAN_AND_EVENT"
PROJECT_ID = "PROJECT_ID"
LOCATION = "us-central1"
MODEL = "gemini-2.5-flash"
PROMPT = "Can you add 2 and 8"
PROMPT = "Can you add 2 and 8"
# GEMINI_API_KEY env var only needed if checking the interactions API.. don't commit it to the actual repo.
# GEMINI_API_KEY="[GEMINI_API_KEY]"
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ version = "0.1.0"
requires-python = ">=3.13"
dependencies = [
"opentelemetry-instrumentation-google-genai",
"google-genai",
"google-genai>=2.0.0",
"pyOpenSSL",
"opentelemetry-sdk",
"opentelemetry-exporter-otlp-proto-grpc",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,18 @@
instrument_generate_content,
uninstrument_generate_content,
)
from .interactions import (
instrument_interactions,
uninstrument_interactions,
)


class GoogleGenAiSdkInstrumentor(BaseInstrumentor):
def __init__(
self, generate_content_config_key_allowlist: Optional[AllowList] = None
):
self._generate_content_snapshot = None
self._interactions_snapshot = None
self._generate_content_config_key_allowlist = (
generate_content_config_key_allowlist
or AllowList.from_env(
Expand Down Expand Up @@ -56,6 +61,10 @@ def _instrument(self, **kwargs: Any):
telemetry_handler,
generate_content_config_key_allowlist=self._generate_content_config_key_allowlist,
)
self._interactions_snapshot = instrument_interactions(
telemetry_handler,
)

def _uninstrument(self, **kwargs: Any):
uninstrument_generate_content(self._generate_content_snapshot)
uninstrument_interactions(self._interactions_snapshot)
Loading