From 68980642e1343cfd9373459e768c4c7731aa86e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arma=C3=ABl=20Gu=C3=A9neau?= Date: Thu, 25 Apr 2024 22:03:07 +0200 Subject: [PATCH] Add a metrics counter measuring in-flight requests --- src/https.rs | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/src/https.rs b/src/https.rs index 9d92470..20df354 100644 --- a/src/https.rs +++ b/src/https.rs @@ -41,9 +41,21 @@ pub struct HttpsConfig { struct HttpsMetrics { requests_received: metrics::Counter, requests_served: metrics::Counter, + requests_in_flight: metrics::UpDownCounter, request_proxy_duration: metrics::Histogram, } +struct InFlightGuard<'a> { + metrics: Arc, + tags: &'a [KeyValue], +} + +impl<'a> Drop for InFlightGuard<'a> { + fn drop(&mut self) { + self.metrics.requests_in_flight.add(-1, self.tags) + } +} + pub async fn serve_https( config: HttpsConfig, cert_store: Arc, @@ -62,6 +74,10 @@ pub async fn serve_https( .u64_counter("https_requests_served") .with_description("Total number of requests served over HTTPS") .init(), + requests_in_flight: meter + .i64_up_down_counter("https_requests_in_flight") + .with_description("Current number of requests handled over HTTPS") + .init(), request_proxy_duration: meter .f64_histogram("https_request_proxy_duration") .with_description("Duration between time when request was received, and time when backend returned status code and headers") @@ -163,8 +179,8 @@ async fn handle_request( ) -> Result, Infallible> { let method_tag = KeyValue::new("method", req.method().to_string()); - // The host tag is only included in the requests_received metric, - // as for other metrics it can easily lead to cardinality explosions. + // The host tag is only included in the requests_received and requests_in_flight + // metrics, as for other metrics it can easily lead to cardinality explosions. let host_tag = KeyValue::new( "host", req.uri() @@ -178,9 +194,13 @@ async fn handle_request( .unwrap_or_default(), ); - metrics - .requests_received - .add(1, &[host_tag, method_tag.clone()]); + let tags = [host_tag, method_tag.clone()]; + metrics.requests_received.add(1, &tags); + metrics.requests_in_flight.add(1, &tags); + let _guard = InFlightGuard { + metrics: Arc::clone(&metrics), + tags: &tags, + }; let mut tags = vec![method_tag]; let resp = select_target_and_proxy(