Skip to content

Commit d3cf6f3

Browse files
authored
refactor(outbound): simplify http route metric labeling (#3604)
The outbound HTTP route labels use multiple ExtractParam implementations to convert a matched route target to set of labels (using an HTTP request). This change removes the RouteLabelExtract type, in favor of implementing label extraction on the route target type directly.
1 parent 768f5a7 commit d3cf6f3

File tree

7 files changed

+44
-66
lines changed

7 files changed

+44
-66
lines changed

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

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ where
8888
Self: svc::Param<classify::Request>,
8989
Self: svc::Param<extensions::Params>,
9090
Self: metrics::MkStreamLabel,
91+
Self: svc::ExtractParam<metrics::labels::Route, http::Request<http::BoxBody>>,
9192
MatchedBackend<T, M, F>: filters::Apply,
9293
MatchedBackend<T, M, F>: metrics::MkStreamLabel,
9394
{
@@ -123,21 +124,13 @@ where
123124
// leaking tasks onto the runtime.
124125
.push_on_service(svc::LoadShed::layer())
125126
.push(filters::NewApplyFilters::<Self, _, _>::layer())
126-
.push({
127-
let mk = Self::label_extractor;
128-
let metrics = metrics.retry.clone();
129-
retry::NewHttpRetry::layer_via_mk(mk, metrics)
130-
})
127+
.push(retry::NewHttpRetry::<Self, _>::layer(metrics.retry.clone()))
131128
.check_new::<Self>()
132129
.check_new_service::<Self, http::Request<http::BoxBody>>()
133130
// Set request extensions based on the route configuration
134131
// AND/OR headers
135132
.push(extensions::NewSetExtensions::layer())
136-
.push(metrics::layer(
137-
&metrics.requests,
138-
Self::label_extractor,
139-
&metrics.body_data,
140-
))
133+
.push(metrics::layer(&metrics.requests, &metrics.body_data))
141134
.check_new::<Self>()
142135
.check_new_service::<Self, http::Request<http::BoxBody>>()
143136
// Configure a classifier to use in the endpoint stack.
@@ -176,6 +169,16 @@ impl<T> filters::Apply for Http<T> {
176169
}
177170
}
178171

172+
impl<B, T> svc::ExtractParam<metrics::labels::Route, http::Request<B>> for Http<T> {
173+
fn extract_param(&self, req: &http::Request<B>) -> metrics::labels::Route {
174+
metrics::labels::Route::new(
175+
self.params.parent_ref.clone(),
176+
self.params.route_ref.clone(),
177+
req.uri(),
178+
)
179+
}
180+
}
181+
179182
impl<T> metrics::MkStreamLabel for Http<T> {
180183
type StatusLabels = metrics::labels::HttpRouteRsp;
181184
type DurationLabels = metrics::labels::Route;
@@ -232,6 +235,16 @@ impl<T> filters::Apply for Grpc<T> {
232235
}
233236
}
234237

238+
impl<B, T> svc::ExtractParam<metrics::labels::Route, http::Request<B>> for Grpc<T> {
239+
fn extract_param(&self, req: &http::Request<B>) -> metrics::labels::Route {
240+
metrics::labels::Route::new(
241+
self.params.parent_ref.clone(),
242+
self.params.route_ref.clone(),
243+
req.uri(),
244+
)
245+
}
246+
}
247+
235248
impl<T> metrics::MkStreamLabel for Grpc<T> {
236249
type StatusLabels = metrics::labels::GrpcRouteRsp;
237250
type DurationLabels = metrics::labels::Route;

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use super::{backend::metrics as backend, retry};
22
use linkerd_app_core::{
33
metrics::prom::{self, EncodeLabelSetMut},
4+
proxy::http,
45
svc,
56
};
67
use linkerd_http_prom::{
@@ -60,25 +61,24 @@ pub type NewRecordDuration<T, M, N> =
6061
#[derive(Clone, Debug)]
6162
pub struct ExtractRecordDurationParams<M>(pub M);
6263

63-
pub fn layer<T, N, X>(
64+
pub fn layer<T, N>(
6465
metrics: &RequestMetrics<T::StreamLabel>,
65-
mk: X,
6666
body_data: &RequestBodyFamilies<labels::Route>,
6767
) -> impl svc::Layer<
6868
N,
6969
Service = NewRecordBodyData<
7070
NewRecordDuration<T, RequestMetrics<T::StreamLabel>, N>,
71-
X,
72-
labels::RouteLabelExtract,
71+
(),
72+
T,
7373
labels::Route,
7474
>,
7575
>
7676
where
7777
T: Clone + MkStreamLabel,
78-
X: Clone,
78+
T: svc::ExtractParam<labels::Route, http::Request<http::BoxBody>>,
7979
{
8080
let record = NewRecordDuration::layer_via(ExtractRecordDurationParams(metrics.clone()));
81-
let body_data = NewRecordBodyData::new(mk, body_data.clone());
81+
let body_data = NewRecordBodyData::new((), body_data.clone());
8282

8383
svc::layer::mk(move |inner| {
8484
use svc::Layer;

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

Lines changed: 1 addition & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
//! Prometheus label types.
22
use linkerd_app_core::{
3-
dns, errors, metrics::prom::EncodeLabelSetMut, proxy::http, svc::ExtractParam,
4-
Error as BoxError,
3+
dns, errors, metrics::prom::EncodeLabelSetMut, proxy::http, Error as BoxError,
54
};
65
use prometheus_client::encoding::*;
76

@@ -40,9 +39,6 @@ pub struct GrpcRsp {
4039
pub error: Option<Error>,
4140
}
4241

43-
#[derive(Clone, Debug)]
44-
pub struct RouteLabelExtract(pub ParentRef, pub RouteRef);
45-
4642
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
4743
pub enum Error {
4844
FailFast,
@@ -215,37 +211,6 @@ impl EncodeLabelSet for GrpcRsp {
215211
}
216212
}
217213

218-
// === impl MatchedRoute ===
219-
220-
impl<T, M, F, P> super::super::MatchedRoute<T, M, F, P> {
221-
/// Returns a [`RouteLabelExtract`].
222-
///
223-
/// The extractor returned by this function provides a [`ExtractParam<P, T>`] implementation
224-
/// that can be used to acquire the route-level labels corresponding to a given outbound
225-
/// request.
226-
pub(crate) fn label_extractor(&self) -> RouteLabelExtract {
227-
use super::super::Route;
228-
let Route {
229-
parent_ref,
230-
route_ref,
231-
..
232-
} = &self.params;
233-
234-
RouteLabelExtract(parent_ref.clone(), route_ref.clone())
235-
}
236-
}
237-
238-
// === impl RouteLabelExtract ===
239-
240-
impl<B> ExtractParam<Route, http::Request<B>> for RouteLabelExtract {
241-
fn extract_param(&self, t: &http::Request<B>) -> Route {
242-
let Self(parent, route) = self;
243-
let uri = t.uri();
244-
245-
Route::new(parent.clone(), route.clone(), uri)
246-
}
247-
}
248-
249214
// === impl Error ===
250215

251216
impl Error {

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

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
use crate::http::policy::route::MatchedRoute;
2-
31
use super::{
42
super::{Grpc, Http, Route},
53
labels,
@@ -593,10 +591,8 @@ pub fn mock_http_route_metrics(
593591
&req,
594592
)
595593
.expect("find default route");
596-
597-
let extract = MatchedRoute::label_extractor;
598594
let (tx, handle) = tower_test::mock::pair::<http::Request<BoxBody>, http::Response<BoxBody>>();
599-
let svc = super::layer(metrics, extract, body_data)
595+
let svc = super::layer(metrics, body_data)
600596
.layer(move |_t: Http<()>| tx.clone())
601597
.new_service(Http {
602598
r#match,
@@ -642,9 +638,8 @@ pub fn mock_grpc_route_metrics(
642638
)
643639
.expect("find default route");
644640

645-
let extract = MatchedRoute::label_extractor;
646641
let (tx, handle) = tower_test::mock::pair::<http::Request<BoxBody>, http::Response<BoxBody>>();
647-
let svc = super::layer(metrics, extract, body_data)
642+
let svc = super::layer(metrics, body_data)
648643
.layer(move |_t: Grpc<()>| tx.clone())
649644
.new_service(Grpc {
650645
r#match,

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

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
use super::{
2-
extensions,
3-
metrics::labels::{Route as RouteLabels, RouteLabelExtract},
4-
};
1+
use super::{extensions, metrics::labels::Route as RouteLabels};
52
use futures::future::{Either, Ready};
63
use linkerd_app_core::{
74
cause_ref, classify,
@@ -15,8 +12,7 @@ use linkerd_http_retry::{self as retry, peek_trailers::PeekTrailersBody};
1512
use linkerd_proxy_client_policy as policy;
1613
use tokio::time;
1714

18-
pub type NewHttpRetry<F, N> =
19-
retry::NewHttpRetry<RetryPolicy, RouteLabels, F, RouteLabelExtract, N>;
15+
pub type NewHttpRetry<X, N> = retry::NewHttpRetry<RetryPolicy, RouteLabels, (), X, N>;
2016

2117
#[derive(Clone, Debug)]
2218
pub struct RetryPolicy {

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ where
6565
route::MatchedRoute<T, M::Summary, F, P>: route::filters::Apply
6666
+ svc::Param<classify::Request>
6767
+ svc::Param<route::extensions::Params>
68-
+ route::metrics::MkStreamLabel,
68+
+ route::metrics::MkStreamLabel
69+
+ svc::ExtractParam<route::metrics::labels::Route, http::Request<http::BoxBody>>,
6970
route::MatchedBackend<T, M::Summary, F>: route::filters::Apply + route::metrics::MkStreamLabel,
7071
{
7172
/// Builds a stack that applies routes to distribute requests over a cached

linkerd/http/retry/src/lib.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,14 @@ struct Metrics {
8585

8686
// === impl NewHttpRetry ===
8787

88+
impl<P, L: Clone, ReqX, N> NewHttpRetry<P, L, (), ReqX, N> {
89+
pub fn layer(
90+
metrics: MetricFamilies<L>,
91+
) -> impl tower::layer::Layer<N, Service = Self> + Clone {
92+
Self::layer_via_mk((), metrics)
93+
}
94+
}
95+
8896
impl<P, L: Clone, X: Clone, ReqX, N> NewHttpRetry<P, L, X, ReqX, N> {
8997
pub fn layer_via_mk(
9098
extract: X,

0 commit comments

Comments
 (0)