Support in-flight request age metrics for router (#16341)

This commit is contained in:
fzyzcjy
2026-01-04 07:38:53 +08:00
committed by GitHub
parent e139d2aa76
commit c88aaf22c7
8 changed files with 428 additions and 9 deletions
+20 -6
View File
@@ -26,7 +26,10 @@ use tracing::{debug, error, field::Empty, info, info_span, warn, Span};
pub use crate::core::token_bucket::TokenBucket;
use crate::{
observability::metrics::{method_to_static_str, metrics_labels, Metrics},
observability::{
inflight_tracker::InFlightRequestTracker,
metrics::{method_to_static_str, metrics_labels, Metrics},
},
routers::error::extract_error_code_from_response,
server::AppState,
wasm::{
@@ -607,12 +610,14 @@ pub async fn concurrency_limit_middleware(
static ACTIVE_HTTP_CONNECTIONS: AtomicU64 = AtomicU64::new(0);
/// Tower Layer for HTTP metrics collection (SMG Layer 1 metrics)
#[derive(Clone, Copy, Default)]
pub struct HttpMetricsLayer;
#[derive(Clone)]
pub struct HttpMetricsLayer {
tracker: Arc<InFlightRequestTracker>,
}
impl HttpMetricsLayer {
pub fn new() -> Self {
Self
pub fn new(tracker: Arc<InFlightRequestTracker>) -> Self {
Self { tracker }
}
}
@@ -620,7 +625,10 @@ impl<S> Layer<S> for HttpMetricsLayer {
type Service = HttpMetricsMiddleware<S>;
fn layer(&self, inner: S) -> Self::Service {
HttpMetricsMiddleware { inner }
HttpMetricsMiddleware {
inner,
in_flight_request_tracker: self.tracker.clone(),
}
}
}
@@ -628,6 +636,7 @@ impl<S> Layer<S> for HttpMetricsLayer {
#[derive(Clone)]
pub struct HttpMetricsMiddleware<S> {
inner: S,
in_flight_request_tracker: Arc<InFlightRequestTracker>,
}
impl<S> Service<Request> for HttpMetricsMiddleware<S>
@@ -651,15 +660,20 @@ where
let start = Instant::now();
let mut inner = self.inner.clone();
let in_flight_request_tracker = self.in_flight_request_tracker.clone();
Box::pin(async move {
// Increment inside async block - ensures no leak if future is dropped before polling
let active = ACTIVE_HTTP_CONNECTIONS.fetch_add(1, Ordering::Relaxed) + 1;
Metrics::set_http_connections_active(active as usize);
let guard = in_flight_request_tracker.track();
// Capture result before decrementing to ensure decrement happens on error too
let result = inner.call(req).await;
drop(guard);
// Always decrement, regardless of success or failure
let active = ACTIVE_HTTP_CONNECTIONS.fetch_sub(1, Ordering::Relaxed) - 1;
Metrics::set_http_connections_active(active as usize);