Skip to content

GenAI Utils | Add agent metrics, and events #4329

Draft
etserend wants to merge 2 commits intoopen-telemetry:mainfrom
etserend:genai-utils/agent-metrics-events
Draft

GenAI Utils | Add agent metrics, and events #4329
etserend wants to merge 2 commits intoopen-telemetry:mainfrom
etserend:genai-utils/agent-metrics-events

Conversation

@etserend
Copy link

@etserend etserend commented Mar 12, 2026

Description

Adds gen_ai.client.operation.duration and gen_ai.client.token.usage histogram metrics along with gen_ai.client.inference.operation.details log events for agent lifecycle operations (create_agent, invoke_agent).

Demo app PR: #4343
Sample metrics output:

Metrics — gen_ai.client.operation.duration (Histogram, unit: s)
├── Data Point 1 — create_agent (local, ~0ms)
│   ├── gen_ai.operation.name: create_agent
│   ├── gen_ai.request.model: gemini-2.5-flash
│   ├── gen_ai.provider.name: gcp_vertex_ai
│   └── server.address: us-central1-aiplatform.googleapis.com
│
├── Data Point 2 — create_agent (deploy, ~259.75s)
│   ├── gen_ai.operation.name: create_agent
│   ├── gen_ai.request.model: gemini-2.5-flash
│   ├── gen_ai.provider.name: gcp_vertex_ai
│   └── server.address: us-central1-aiplatform.googleapis.com
│
└── Data Point 3 — invoke_agent (~3.16s)
    ├── gen_ai.operation.name: invoke_agent
    ├── gen_ai.request.model: gemini-2.5-flash
    ├── gen_ai.provider.name: gcp_vertex_ai
    └── server.address: us-central1-aiplatform.googleapis.com

Metrics — gen_ai.client.token.usage (Histogram, unit: {token})
├── Data Point 1 — input tokens (invoke_agent)
│   ├── gen_ai.operation.name: invoke_agent
│   ├── gen_ai.request.model: gemini-2.5-flash
│   ├── gen_ai.provider.name: gcp_vertex_ai
│   ├── gen_ai.token.type: input
│   ├── server.address: us-central1-aiplatform.googleapis.com
│   └── value: 12
│
└── Data Point 2 — output tokens (invoke_agent)
    ├── gen_ai.operation.name: invoke_agent
    ├── gen_ai.request.model: gemini-2.5-flash
    ├── gen_ai.provider.name: gcp_vertex_ai
    ├── gen_ai.token.type: output
    ├── server.address: us-central1-aiplatform.googleapis.com
    └── value: 105

Sample events output:

Events — gen_ai.client.inference.operation.details (3 log records)
│
├── Event 1 — create_agent (trace: e7f8a7cd..., scope: opentelemetry.util.genai.handler v0.3b0.dev)
│   ├── gen_ai.operation.name: create_agent
│   ├── gen_ai.agent.name: Currency Exchange Agent
│   ├── gen_ai.agent.description: Deploying agent to Vertex AI Agent Engine
│   ├── gen_ai.provider.name: gcp_vertex_ai
│   ├── gen_ai.request.model: gemini-2.5-flash
│   └── server.address: us-central1-aiplatform.googleapis.com
│
├── Event 2 — invoke_agent (trace: 4dc8827b..., scope: opentelemetry.util.genai.handler v0.3b0.dev)
│   ├── gen_ai.operation.name: invoke_agent
│   ├── gen_ai.agent.name: Currency Exchange Agent
│   ├── gen_ai.agent.description: Currency exchange agent demo
│   ├── gen_ai.provider.name: gcp_vertex_ai
│   ├── gen_ai.request.model: gemini-2.5-flash
│   ├── gen_ai.response.finish_reasons:
│   ├── gen_ai.usage.input_tokens: 12
│   ├── gen_ai.usage.output_tokens: 105
│   └── server.address: us-central1-aiplatform.googleapis.com
│
└── Event 3 — chat (trace: 4dc8827b..., scope: opentelemetry.instrumentation.vertexai)
    ├── gen_ai.operation.name: chat
    ├── gen_ai.request.model: gemini-2.5-flash
    ├── gen_ai.response.model: gemini-2.5-flash
    ├── gen_ai.response.finish_reasons:
    ├── gen_ai.usage.input_tokens: 12
    ├── gen_ai.usage.output_tokens: 105
    ├── gen_ai.input.messages: [{"parts":[{"content":"What is the ex...
    ├── gen_ai.output.messages: [{"finish_reason":"stop","parts":[{"...
    ├── server.address: us-central1-aiplatform.googleapis.com
    └── server.port: 443

Fixes # (issue)

Type of change

  • New feature (non-breaking change which adds functionality)

Does This PR Require a Core Repo Change?

  • No.

Checklist:

See contributing.md for styleguide, changelog guidelines, and more.

  • Followed the style guidelines of this project
  • Changelogs have been updated
  • Unit tests have been added
  • Documentation has been updated

@etserend etserend force-pushed the genai-utils/agent-metrics-events branch from d1959e6 to 8f2f3e1 Compare March 12, 2026 18:12
attributes[error_attributes.ERROR_TYPE] = error_type

if duration_seconds is not None:
self._duration_histogram.record(

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might need to emit gen_ai.agent.duration metric to capture the agent duration and operation duration might not suffice. Is gen_ai.agent.duration part of the sem conv?

tool_definitions: list[dict[str, Any]] | None = None

# Span kind: CLIENT for remote agents, INTERNAL for in-process agents
is_remote: bool = True

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is the default value True? Are we assuming the invoke agents will be a remote agent call by default and not an in-process agent?

Also, SpanContext already has a field to check for is remote - https://opentelemetry.io/docs/specs/otel/trace/api/#isremote. Maybe we can use that

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants