Add conversation ID to OTEL metrics
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_usagecodex.turn.e2e_duration_mscodex.turn.network_proxycodex.websocket.eventcodex.websocket.event.duration_ms
These metrics had tags like:
app.versionauth_modemodeloriginatorsession_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
- Start Codex with OTEL logs and metrics export enabled.
- Run a normal interactive conversation and perform a few turns.
- Inspect exported logs and metrics.
- 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_modesession_sourceoriginatorservice_namemodelapp.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.idin 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
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗