Skip to content

Commit e4d7d57

Browse files
authored
feat(app): Route frame count metrics (#3334)
### ⛅ overview this introduces a new tower middleware for Prometheus metrics, used for instrumenting HTTP and gRPC request bodies, and observing (a) the number of frames yielded by a body, (b) the number of bytes included in body frames, and (c) a distribution of the size of frames yielded. this builds upon the backend-level metrics added in #3308. this additionally uses the route label extractor, hoisted out of the retry middleware's Prometheus telemetry in #3337. ### 📝 changes * a `linkerd_http_prom::body_data::request::NewRecordBodyData::NewRecordBodyData` middleware is added, which complements the equivalent `linkerd_http_prom::body_data::response` middleware. * this is added to policy routes' metrics layer. see prometheus/client_rust#241 and prometheus/client_rust#242, which track upstream proposals to add accessors to `Histogram` that will allow us to make test assertions that metrics are working properly. for now, these are feature gated as also done in #3308. Signed-off-by: katelyn martin <[email protected]>
1 parent 621ea19 commit e4d7d57

File tree

5 files changed

+424
-29
lines changed

5 files changed

+424
-29
lines changed

linkerd/app/outbound/src/http/logical/policy/route.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,11 @@ where
133133
// Set request extensions based on the route configuration
134134
// AND/OR headers
135135
.push(extensions::NewSetExtensions::layer())
136-
.push(metrics::layer(&metrics.requests))
136+
.push(metrics::layer(
137+
&metrics.requests,
138+
Self::label_extractor,
139+
&metrics.body_data,
140+
))
137141
.check_new::<Self>()
138142
.check_new_service::<Self, http::Request<http::BoxBody>>()
139143
// Configure a classifier to use in the endpoint stack.

linkerd/app/outbound/src/http/logical/policy/route/metrics.rs

+29-4
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ use linkerd_app_core::{
33
metrics::prom::{self, EncodeLabelSetMut},
44
svc,
55
};
6-
use linkerd_http_prom::record_response::{self, StreamLabel};
6+
use linkerd_http_prom::{
7+
body_data::request::{NewRecordBodyData, RequestBodyFamilies},
8+
record_response::{self, StreamLabel},
9+
};
710

811
pub use linkerd_http_prom::record_response::MkStreamLabel;
912

@@ -23,6 +26,7 @@ pub struct RouteMetrics<R: StreamLabel, B: StreamLabel> {
2326
pub(super) retry: retry::RouteRetryMetrics,
2427
pub(super) requests: RequestMetrics<R>,
2528
pub(super) backend: backend::RouteBackendMetrics<B>,
29+
pub(super) body_data: RequestBodyFamilies<labels::Route>,
2630
}
2731

2832
pub type HttpRouteMetrics = RouteMetrics<LabelHttpRouteRsp, LabelHttpRouteBackendRsp>;
@@ -56,13 +60,30 @@ pub type NewRecordDuration<T, M, N> =
5660
#[derive(Clone, Debug)]
5761
pub struct ExtractRecordDurationParams<M>(pub M);
5862

59-
pub fn layer<T, N>(
63+
pub fn layer<T, N, X>(
6064
metrics: &RequestMetrics<T::StreamLabel>,
61-
) -> impl svc::Layer<N, Service = NewRecordDuration<T, RequestMetrics<T::StreamLabel>, N>> + Clone
65+
mk: X,
66+
body_data: &RequestBodyFamilies<labels::Route>,
67+
) -> impl svc::Layer<
68+
N,
69+
Service = NewRecordBodyData<
70+
NewRecordDuration<T, RequestMetrics<T::StreamLabel>, N>,
71+
X,
72+
labels::RouteLabelExtract,
73+
labels::Route,
74+
>,
75+
>
6276
where
6377
T: Clone + MkStreamLabel,
78+
X: Clone,
6479
{
65-
NewRecordDuration::layer_via(ExtractRecordDurationParams(metrics.clone()))
80+
let record = NewRecordDuration::layer_via(ExtractRecordDurationParams(metrics.clone()));
81+
let body_data = NewRecordBodyData::new(mk, body_data.clone());
82+
83+
svc::layer::mk(move |inner| {
84+
use svc::Layer;
85+
body_data.layer(record.layer(inner))
86+
})
6687
}
6788

6889
// === impl RouteMetrics ===
@@ -89,6 +110,7 @@ impl<R: StreamLabel, B: StreamLabel> Default for RouteMetrics<R, B> {
89110
requests: Default::default(),
90111
backend: Default::default(),
91112
retry: Default::default(),
113+
body_data: Default::default(),
92114
}
93115
}
94116
}
@@ -99,6 +121,7 @@ impl<R: StreamLabel, B: StreamLabel> Clone for RouteMetrics<R, B> {
99121
requests: self.requests.clone(),
100122
backend: self.backend.clone(),
101123
retry: self.retry.clone(),
124+
body_data: self.body_data.clone(),
102125
}
103126
}
104127
}
@@ -113,11 +136,13 @@ impl<R: StreamLabel, B: StreamLabel> RouteMetrics<R, B> {
113136
);
114137

115138
let retry = retry::RouteRetryMetrics::register(reg.sub_registry_with_prefix("retry"));
139+
let body_data = RequestBodyFamilies::register(reg);
116140

117141
Self {
118142
requests,
119143
backend,
120144
retry,
145+
body_data,
121146
}
122147
}
123148

0 commit comments

Comments
 (0)