Skip to content

Commit dde8a9a

Browse files
authored
fix(server): log polled request responses at debug (#3974)
log_response has always logged every gateway response at INFO, including health probes and the GetSandboxConfig and provider-readiness polls each supervisor makes. #3915 demoted the request spans for those polled paths to DEBUG, which stripped the request{method path} prefix from the log line at INFO but left the line itself, so the gateway log fills with bare 'response status=200' lines several times per second. Follow the span's level: polled requests log their response at DEBUG, or WARN on a 5xx so probe and poll failures stay visible. Signed-off-by: Kris Hicks <khicks@nvidia.com>
1 parent 912a077 commit dde8a9a

1 file changed

Lines changed: 57 additions & 5 deletions

File tree

‎crates/openshell-server/src/multiplex.rs‎

Lines changed: 57 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -145,11 +145,17 @@ fn log_response<B>(res: &Response<B>, latency: Duration, span: &Span) {
145145
if status.is_server_error() {
146146
crate::otel_tracing::mark_error(span);
147147
}
148-
tracing::info!(
149-
status = status.as_u16(),
150-
latency_ms = latency.as_millis(),
151-
"response"
152-
);
148+
// Polled requests get a DEBUG span, which is `None` when filtered out.
149+
let polled = span
150+
.metadata()
151+
.is_none_or(|m| *m.level() == tracing::Level::DEBUG);
152+
let server_error = status.is_server_error();
153+
let (status, latency_ms) = (status.as_u16(), latency.as_millis());
154+
match (polled, server_error) {
155+
(false, _) => tracing::info!(status, latency_ms, "response"),
156+
(true, true) => tracing::warn!(status, latency_ms, "response"),
157+
(true, false) => tracing::debug!(status, latency_ms, "response"),
158+
}
153159
}
154160

155161
fn record_response_trailers(
@@ -2261,6 +2267,52 @@ mod tests {
22612267
);
22622268
}
22632269

2270+
#[test]
2271+
fn polled_path_responses_log_at_debug() {
2272+
let log_buf: Arc<Mutex<Vec<u8>>> = Arc::new(Mutex::new(Vec::new()));
2273+
let writer = TraceBuf(log_buf.clone());
2274+
let subscriber = {
2275+
use tracing_subscriber::layer::SubscriberExt as _;
2276+
tracing_subscriber::registry()
2277+
.with(tracing_subscriber::filter::LevelFilter::INFO)
2278+
.with(
2279+
tracing_subscriber::fmt::layer()
2280+
.with_writer(move || writer.clone())
2281+
.with_ansi(false),
2282+
)
2283+
};
2284+
{
2285+
let _traced = crate::otel_tracing::test_exporter::install_scoped(subscriber);
2286+
let respond = |path: &str, status: u16| {
2287+
let req = Request::builder()
2288+
.uri(path)
2289+
.body(Empty::<Bytes>::new())
2290+
.unwrap();
2291+
let res = Response::builder()
2292+
.status(status)
2293+
.body(Empty::<Bytes>::new())
2294+
.unwrap();
2295+
log_response(&res, Duration::from_millis(1), &make_request_span(&req));
2296+
};
2297+
respond("/openshell.v1.OpenShell/GetSandboxConfig", 200);
2298+
respond("/healthz", 200);
2299+
respond("/openshell.v1.OpenShell/CreateSandbox", 201);
2300+
respond("/healthz", 503);
2301+
}
2302+
2303+
let output = String::from_utf8(log_buf.lock().unwrap().clone()).unwrap();
2304+
let lines: Vec<&str> = output.lines().collect();
2305+
assert_eq!(lines.len(), 2, "got: {output}");
2306+
assert!(
2307+
lines[0].contains("INFO") && lines[0].contains("status=201"),
2308+
"got: {output}"
2309+
);
2310+
assert!(
2311+
lines[1].contains("WARN") && lines[1].contains("status=503"),
2312+
"got: {output}"
2313+
);
2314+
}
2315+
22642316
/// The `TraceLayer` creates the server span, so no gRPC handler needs
22652317
/// `#[instrument]`. The request ID carries into it so a trace can be
22662318
/// correlated with the gateway's logs.

0 commit comments

Comments
 (0)