Record actual Responses endpoints in tracing spans (#40906)

## Why

Responses-compatible requests can use routes other than `/responses`, but their
tracing spans reported the default route regardless of the selected endpoint.

## What changed

- Populate `api.path` from the selected `ResponsesEndpoint` for HTTP and
  WebSocket requests.
- Retain the endpoint on WebSocket connections so stream-request spans report
  the same route as connection spans.

GitOrigin-RevId: 349eca94b27d4cc3a1adde8b257313506bdaf0f4
This commit is contained in:
jif
2026-08-26 15:09:15 +00:00
committed by copyberry
parent d4998d611a
commit bde9db1375
3 changed files with 14 additions and 7 deletions

View File

@@ -96,7 +96,7 @@ impl<T: HttpTransport> ResponsesClient<T> {
fields(
transport = "responses_http",
http.method = "POST",
api.path = "responses"
api.path = self.endpoint.path()
)
)]
pub async fn stream_request(
@@ -136,7 +136,7 @@ impl<T: HttpTransport> ResponsesClient<T> {
fields(
transport = "responses_http",
http.method = "POST",
api.path = "responses",
api.path = self.endpoint.path(),
turn.has_state = turn_state.is_some()
)
)]

View File

@@ -182,6 +182,7 @@ struct ResponsesWebsocketTimingLogContext {
pub struct ResponsesWebsocketConnection {
stream: Arc<Mutex<Option<WsStream>>>,
endpoint: ResponsesEndpoint,
// TODO (pakrym): is this the right place for timeout?
idle_timeout: Duration,
server_reasoning_included: bool,
@@ -193,6 +194,7 @@ impl std::fmt::Debug for ResponsesWebsocketConnection {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("ResponsesWebsocketConnection")
.field("stream", &"<ws-stream>")
.field("endpoint", &self.endpoint)
.field("idle_timeout", &self.idle_timeout)
.field("server_reasoning_included", &self.server_reasoning_included)
.field("server_model", &self.server_model)
@@ -208,9 +210,11 @@ impl ResponsesWebsocketConnection {
server_reasoning_included: bool,
server_model: Option<String>,
telemetry: Option<Arc<dyn WebsocketTelemetry>>,
endpoint: ResponsesEndpoint,
) -> Self {
Self {
stream: Arc::new(Mutex::new(Some(stream))),
endpoint,
idle_timeout,
server_reasoning_included,
server_model,
@@ -226,7 +230,7 @@ impl ResponsesWebsocketConnection {
name = "responses_websocket.stream_request",
level = "info",
skip_all,
fields(transport = "responses_websocket", api.path = "responses")
fields(transport = "responses_websocket", api.path = self.endpoint.path())
)]
pub async fn stream_request(
&self,
@@ -388,7 +392,7 @@ impl ResponsesWebsocketClient {
name = "responses_websocket.connect",
level = "info",
skip_all,
fields(transport = "responses_websocket", api.path = "responses")
fields(transport = "responses_websocket", api.path = self.endpoint.path())
)]
pub async fn connect(
&self,
@@ -415,6 +419,7 @@ impl ResponsesWebsocketClient {
server_reasoning_included,
server_model,
telemetry,
self.endpoint,
))
}

View File

@@ -1416,7 +1416,7 @@ impl ModelClientSession {
provider = %self.client.state.provider.info().name,
wire_api = %self.client.state.provider.info().wire_api,
transport = "responses_websocket",
api.path = "responses",
api.path = params.endpoint.path(),
turn.has_metadata_header = params.responses_metadata.has_turn_metadata()
)
)]
@@ -1504,7 +1504,7 @@ impl ModelClientSession {
wire_api = %self.client.state.provider.info().wire_api,
transport = "responses_http",
http.method = "POST",
api.path = "responses",
api.path = tracing::field::Empty,
turn.has_metadata_header = responses_metadata.has_turn_metadata()
)
)]
@@ -1530,6 +1530,7 @@ impl ModelClientSession {
let endpoint = self
.client
.responses_endpoint(client_setup.auth.as_ref(), &model_info.slug);
tracing::Span::current().record("api.path", endpoint.path());
let transport = self
.client
.build_api_transport(&client_setup.api_provider, endpoint.path())?;
@@ -1657,7 +1658,7 @@ impl ModelClientSession {
model = %model_info.slug,
wire_api = %self.client.state.provider.info().wire_api,
transport = "responses_websocket",
api.path = "responses",
api.path = tracing::field::Empty,
turn.has_metadata_header = responses_metadata.has_turn_metadata(),
websocket.warmup = warmup
)
@@ -1688,6 +1689,7 @@ impl ModelClientSession {
let endpoint = self
.client
.responses_endpoint(client_setup.auth.as_ref(), &model_info.slug);
tracing::Span::current().record("api.path", endpoint.path());
let request_auth_context = AuthRequestTelemetryContext::new(
client_setup.auth.as_ref().map(CodexAuth::auth_mode),
client_setup.api_auth.as_ref(),