Files
codex/codex-rs/exec-server/src/rpc_timing.rs
T
Adam Perry @ OpenAI 6fa3bcaae8 Add exec-server RPC timing and process startup tracing (#47680)
## Why

Detached work can keep request spans open beyond response enqueueing. Record explicit phase timings to distinguish request handling from the full span lifetime.

## What changed

- Record server dispatch and response enqueue offsets from request receipt, plus a response enqueue event for HTTP responses that bypass the dispatcher.
- Emit client request enqueue and response receipt events, including success or server-error outcomes and reader-to-caller delay. Carry completion timestamps to the awaiting task so receipt events retain its tracing context.
- Add spans for process startup, sandbox preparation, shell snapshot preparation and capture, and process spawning. Record process identifiers only when nonempty and at most 64 bytes long.

GitOrigin-RevId: 237db898b3284fe8a6a36cb0055b3c7991d8e8a4
2026-09-23 22:10:28 +00:00

45 lines
1.3 KiB
Rust

//! Carries RPC reader completion time back to the caller so tracing stays in the awaiting task.
use std::time::Instant;
use serde_json::Value;
use crate::rpc::RpcCallError;
pub(crate) struct RpcCompletion {
pub(crate) result: Result<Value, RpcCallError>,
completed_at: Instant,
}
impl RpcCompletion {
pub(crate) fn new(result: Result<Value, RpcCallError>) -> Self {
Self {
result,
completed_at: Instant::now(),
}
}
pub(crate) fn record_receipt(&self, method: &str) {
let outcome = match &self.result {
Ok(_) => "success",
Err(RpcCallError::Server(_)) => "error",
Err(
RpcCallError::Closed
| RpcCallError::Json(_)
| RpcCallError::TimedOut { .. }
| RpcCallError::PendingRequestLimitExceeded { .. },
) => return,
};
tracing::event!(
name: "codex.exec_server.response_received",
target: "codex_otel.trace_safe",
tracing::Level::INFO,
event.name = "codex.exec_server.response_received",
rpc.method = method,
outcome,
reader_to_caller_ns = i64::try_from(self.completed_at.elapsed().as_nanos())
.unwrap_or(i64::MAX),
);
}
}