don't
5
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat(knot): generate response status and latency metrics

Signed-off-by: tjh <x@tjh.dev>

tjh 732b018d 71f18c12

+20
+1
Cargo.lock
··· 2164 2164 "http-body-util", 2165 2165 "hyper-util", 2166 2166 "maud", 2167 + "metrics", 2167 2168 "metrics-exporter-prometheus", 2168 2169 "mimetype-detector", 2169 2170 "moka",
+1
crates/gordian-knot/Cargo.toml
··· 21 21 data-encoding.workspace = true 22 22 exn.workspace = true 23 23 gix.workspace = true 24 + metrics.workspace = true 24 25 rand.workspace = true 25 26 reqwest.workspace = true 26 27 serde.workspace = true
+18
crates/gordian-knot/src/cli/serve.rs
··· 6 6 use std::time::Duration; 7 7 8 8 use anyhow::Context as _; 9 + use axum::extract::OriginalUri; 9 10 use axum::http::Request; 10 11 use axum::http::Response; 12 + use axum::middleware::map_response; 11 13 use clap::ArgAction; 12 14 use clap::Args; 13 15 use clap::ValueEnum; ··· 355 353 // Build the public API. 356 354 let router = gordian_knot::public::router() 357 355 .layer(RequestDecompressionLayer::new()) 356 + .layer(map_response(copy_uri_to_response)) 358 357 .layer( 359 358 ServiceBuilder::new() 360 359 .set_x_request_id(MakeRequestUuid) ··· 450 447 }; 451 448 } 452 449 450 + async fn copy_uri_to_response<B>(uri: OriginalUri, mut response: Response<B>) -> Response<B> { 451 + response.extensions_mut().insert(uri); 452 + response 453 + } 454 + 453 455 make_span!(PublicHttpSpan, "public"); 454 456 make_span!(PrivateHttpSpan, "private"); 455 457 ··· 463 455 464 456 impl<B> OnResponse<B> for TraceResponse { 465 457 fn on_response(self, response: &Response<B>, latency: Duration, _: &Span) { 458 + if let Some(uri) = response.extensions().get::<OriginalUri>() { 459 + let labels = [ 460 + ("path", uri.path().to_string()), 461 + ("status", response.status().as_u16().to_string()), 462 + ]; 463 + 464 + metrics::counter!("knot_response", &labels).increment(1); 465 + metrics::histogram!("knot_response_latency", &labels).record(latency); 466 + } 467 + 466 468 match response.status() { 467 469 status if status.is_success() => tracing::trace!(?status, ?latency), 468 470 status if status.is_client_error() => tracing::warn!(?status, ?latency),