Add conversation ID to OTEL metrics

Resolved 💬 2 comments Opened Mar 26, 2026 by gusholcomb Closed May 10, 2026

Summary

Codex OTEL logs include conversation.id, but Codex OTEL metrics do not include conversation.id in metric attributes or resource attributes.

That makes it impossible for downstream collectors to reliably correlate metrics with a specific Codex conversation/thread.

What I observed

In a live Codex conversation:

  • conversation.id = 019d2bae-7c39-7c73-b058-7b45e6aabef7

OTEL logs for that conversation include:

  • conversation.id = 019d2bae-7c39-7c73-b058-7b45e6aabef7

But OTEL metrics emitted during the same conversation contain neither:

  • attributes["conversation.id"]
  • resource_attributes["conversation.id"]

As a result, the metric rows arrive with no conversation identity and cannot be joined back to the conversation.

Concrete downstream impact

I’m ingesting Codex OTEL data into a local observability tool.

For the conversation above:

  • logs were correlated to 019d2bae-7c39-7c73-b058-7b45e6aabef7
  • metrics existed for the same time window
  • but none of the metric rows included conversation.id

Example metric names seen during the conversation:

  • codex.turn.token_usage
  • codex.turn.e2e_duration_ms
  • codex.turn.network_proxy
  • codex.websocket.event
  • codex.websocket.event.duration_ms

These metrics had tags like:

  • app.version
  • auth_mode
  • model
  • originator
  • session_source

but no conversation.id.

Expected behavior

Codex metrics should include the same conversation.id that is already attached to logs/traces for the conversation.

Actual behavior

Logs/traces carry conversation.id, but metrics omit it.

Repro

  1. Start Codex with OTEL logs and metrics export enabled.
  2. Run a normal interactive conversation and perform a few turns.
  3. Inspect exported logs and metrics.
  4. Compare attributes:
  • logs contain conversation.id
  • metrics do not

Code pointers

Logs/traces include conversation.id

codex-rs/otel/src/events/shared.rs

conversation.id = %$self.metadata.conversation_id,

This is present in both the log and trace event macros.

Metrics do not include conversation.id

codex-rs/otel/src/events/session_telemetry.rs

SessionTelemetry stores conversation_id, but metadata_tag_refs() does not include it when building metric tags.

codex-rs/otel/src/metrics/tags.rs

SessionMetricTagValues currently only includes:

  • auth_mode
  • session_source
  • originator
  • service_name
  • model
  • app.version

There is no conversation.id tag.

Tests currently encode the current behavior

codex-rs/otel/tests/suite/manager_metrics.rs

The expected metric attribute sets do not include conversation.id.

Suggested fix

Add conversation.id to the metric metadata tag set emitted by SessionTelemetry.

If cardinality concerns make that undesirable by default, another option would be:

  • a config flag to opt in to conversation-correlated metrics
  • or emitting conversation.id in resource attributes instead of point attributes

Why this matters

Without conversation.id on metrics, downstream OTEL backends and local collectors cannot reliably:

  • join metrics to logs/traces for a specific Codex conversation
  • attribute token/duration/tool metrics to a conversation
  • build accurate per-conversation observability views

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗