mirror of
https://github.com/openai/codex.git
synced 2026-11-11 02:29:10 +00:00
[codex] Add token usage to turn tracing spans (#19432)
## Why Slow Codex turns are easier to debug when token usage is visible in the trace itself, without joining against separate analytics. This adds token usage to existing turn-handling spans for regular user turns only. [Example turn](https://openai.datadoghq.com/apm/trace/9d353efa2cb5de1f4c5b93dc33c3df04?colorBy=service&graphType=flamegraph&shouldShowLegend=true&sort=time&spanID=3555541504891512675&spanViewType=metadata&traceQuery=) <img width="1447" height="967" alt="Screenshot 2026-04-24 at 3 03 07 PM" src="https://github.com/user-attachments/assets/ab7bb187-e7fc-41f0-a366-6c44610b2b2c" /> ## What Changed Added response-level token fields on completed handle_responses spans: gen_ai.usage.input_tokens gen_ai.usage.cache_read.input_tokens gen_ai.usage.output_tokens codex.usage.reasoning_output_tokens codex.usage.total_tokens Added aggregate token fields on regular turn spans: codex.turn.token_usage.* Added an explicit regular-turn opt-in via SessionTask::records_turn_token_usage_on_span() so this is not coupled to span-name strings. ## Testing - `cargo test -p codex-otel` - `cargo test -p codex-core turn_and_completed_response_spans_record_token_usage` - `just fmt` - `just fix -p codex-core` - `just fix -p codex-otel` - Manual local Electron/app-server smoke test: regular user turn emits the new span fields Known status: `cargo test -p codex-core` was attempted and failed in unrelated existing areas: config approvals, request-permissions, git-info ordering, and subagent metadata persistence.
This commit is contained in:
1 parent
640a1b23ea
commit
de2ccf9473
6 files changed
+180
-9
No files matched your search
@@ -79,17 +79,25 @@ pub(crate) struct RunningTask {
|
||||
pub(crate) _timer: Option<codex_otel::Timer>,
|
||||
}
|
||||
|
||||
pub(crate) struct RemovedTask {
|
||||
pub(crate) records_turn_token_usage_on_span: bool,
|
||||
pub(crate) active_turn_is_empty: bool,
|
||||
}
|
||||
|
||||
impl ActiveTurn {
|
||||
pub(crate) fn add_task(&mut self, task: RunningTask) {
|
||||
let sub_id = task.turn_context.sub_id.clone();
|
||||
self.tasks.insert(sub_id, task);
|
||||
}
|
||||
|
||||
pub(crate) fn remove_task(&mut self, sub_id: &str) -> bool {
|
||||
if let Some(task) = self.tasks.swap_remove(sub_id) {
|
||||
task.handle.detach();
|
||||
}
|
||||
self.tasks.is_empty()
|
||||
pub(crate) fn remove_task(&mut self, sub_id: &str) -> Option<RemovedTask> {
|
||||
let task = self.tasks.swap_remove(sub_id)?;
|
||||
let records_turn_token_usage_on_span = task.task.records_turn_token_usage_on_span();
|
||||
task.handle.detach();
|
||||
Some(RemovedTask {
|
||||
records_turn_token_usage_on_span,
|
||||
active_turn_is_empty: self.tasks.is_empty(),
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn drain_tasks(&mut self) -> Vec<RunningTask> {
|
||||
|
||||
Reference in new issue
Block a user