Skip to content

Commit 9b37841

Browse files
committed
feat(app/inbound): response body frame size metrics
#3308 introduced tower middleware to the outbound proxy that records the size and number of response body's data frames. this commit introduces an equivalent layer to the inbound proxy's prometheus metrics. Signed-off-by: katelyn martin <[email protected]>
1 parent 6f58bbf commit 9b37841

File tree

3 files changed

+115
-7
lines changed

3 files changed

+115
-7
lines changed

linkerd/app/inbound/src/http/router.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use linkerd_app_core::{
1010
use std::{fmt, net::SocketAddr};
1111
use tracing::{debug, debug_span};
1212

13-
pub use self::metrics::RequestCountFamilies;
13+
pub use self::metrics::*;
1414

1515
mod metrics;
1616

@@ -245,7 +245,7 @@ impl<C> Inbound<C> {
245245
.push(svc::NewOneshotRoute::layer_via(|t: &policy::Permitted<T>| {
246246
LogicalPerRequest::from(t)
247247
}))
248-
.push(self::metrics::layer(rt.metrics.request_count.clone()))
248+
.push(self::metrics::layer(rt.metrics.request_count.clone(), rt.metrics.response_body_data.clone()))
249249
.check_new_service::<policy::Permitted<T>, http::Request<http::BoxBody>>()
250250
.push(svc::ArcNewService::layer())
251251
.push(policy::NewHttpPolicy::layer(rt.metrics.http_authz.clone()))

linkerd/app/inbound/src/http/router/metrics.rs

Lines changed: 109 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,31 @@ use linkerd_app_core::{
1010
},
1111
svc,
1212
};
13-
use linkerd_http_prom::count_reqs::{NewCountRequests, RequestCount};
13+
use linkerd_http_prom::{
14+
body_data::response::{BodyDataMetrics, NewRecordBodyData},
15+
count_reqs::{NewCountRequests, RequestCount},
16+
};
1417

1518
pub(super) fn layer<N>(
1619
request_count: RequestCountFamilies,
17-
// TODO(kate): other metrics families will added here.
18-
) -> impl svc::Layer<N, Service = NewCountRequests<ExtractRequestCount, N>> {
20+
response_body_metrics: ResponseBodyFamilies,
21+
) -> impl svc::Layer<
22+
N,
23+
Service = NewCountRequests<
24+
ExtractRequestCount,
25+
NewRecordBodyData<ExtractRecordBodyDataMetrics, N>,
26+
>,
27+
> {
1928
svc::layer::mk(move |inner| {
2029
use svc::Layer as _;
2130
let extract = ExtractRequestCount(request_count.clone());
22-
NewCountRequests::layer_via(extract).layer(inner)
31+
32+
NewCountRequests::layer_via(extract).layer(
33+
NewRecordBodyData::layer_via(ExtractRecordBodyDataMetrics(
34+
response_body_metrics.clone(),
35+
))
36+
.layer(inner),
37+
)
2338
})
2439
}
2540

@@ -37,6 +52,20 @@ pub struct RequestCountLabels {
3752
#[derive(Clone, Debug)]
3853
pub struct ExtractRequestCount(pub RequestCountFamilies);
3954

55+
#[derive(Clone, Debug)]
56+
pub struct ResponseBodyFamilies {
57+
grpc: linkerd_http_prom::body_data::response::ResponseBodyFamilies<ResponseBodyDataLabels>,
58+
http: linkerd_http_prom::body_data::response::ResponseBodyFamilies<ResponseBodyDataLabels>,
59+
}
60+
61+
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
62+
pub struct ResponseBodyDataLabels {
63+
route: RouteLabels,
64+
}
65+
66+
#[derive(Clone, Debug)]
67+
pub struct ExtractRecordBodyDataMetrics(ResponseBodyFamilies);
68+
4069
// === impl RequestCountFamilies ===
4170

4271
impl RequestCountFamilies {
@@ -112,3 +141,79 @@ impl EncodeLabelSet for RequestCountLabels {
112141
self.encode_label_set(&mut enc)
113142
}
114143
}
144+
145+
// === impl ResponseBodyFamilies ===
146+
147+
impl ResponseBodyFamilies {
148+
/// Registers a new [`ResponseBodyDataFamilies`] with the given registry.
149+
pub fn register(reg: &mut prom::Registry) -> Self {
150+
let grpc = {
151+
let reg = reg.sub_registry_with_prefix("grpc");
152+
linkerd_http_prom::body_data::response::ResponseBodyFamilies::register(reg)
153+
};
154+
155+
let http = {
156+
let reg = reg.sub_registry_with_prefix("http");
157+
linkerd_http_prom::body_data::response::ResponseBodyFamilies::register(reg)
158+
};
159+
160+
Self { grpc, http }
161+
}
162+
163+
/// Fetches the proper body frame metrics family, given a permitted target.
164+
fn family<T>(
165+
&self,
166+
permitted: &Permitted<T>,
167+
) -> &linkerd_http_prom::body_data::response::ResponseBodyFamilies<ResponseBodyDataLabels> {
168+
let Self { grpc, http } = self;
169+
match permitted {
170+
Permitted::Grpc { .. } => grpc,
171+
Permitted::Http { .. } => http,
172+
}
173+
}
174+
}
175+
176+
// === impl ResponseBodyDataLabels ===
177+
178+
impl EncodeLabelSetMut for ResponseBodyDataLabels {
179+
fn encode_label_set(&self, enc: &mut LabelSetEncoder<'_>) -> std::fmt::Result {
180+
use encoding::EncodeLabel as _;
181+
182+
let Self {
183+
route:
184+
RouteLabels {
185+
server: ServerLabel(parent, port),
186+
route,
187+
},
188+
} = self;
189+
190+
("parent_group", parent.group()).encode(enc.encode_label())?;
191+
("parent_kind", parent.kind()).encode(enc.encode_label())?;
192+
("parent_name", parent.name()).encode(enc.encode_label())?;
193+
("parent_port", *port).encode(enc.encode_label())?;
194+
195+
("route_group", route.group()).encode(enc.encode_label())?;
196+
("route_kind", route.kind()).encode(enc.encode_label())?;
197+
("route_name", route.name()).encode(enc.encode_label())?;
198+
199+
Ok(())
200+
}
201+
}
202+
203+
impl EncodeLabelSet for ResponseBodyDataLabels {
204+
fn encode(&self, mut enc: LabelSetEncoder<'_>) -> std::fmt::Result {
205+
self.encode_label_set(&mut enc)
206+
}
207+
}
208+
209+
// === impl ExtractRecordBodyDataMetrics ===
210+
211+
impl<T> svc::ExtractParam<BodyDataMetrics, Permitted<T>> for ExtractRecordBodyDataMetrics {
212+
fn extract_param(&self, permitted: &Permitted<T>) -> BodyDataMetrics {
213+
let Self(families) = self;
214+
let family = families.family(permitted);
215+
let route = permitted.route_labels();
216+
217+
family.metrics(&ResponseBodyDataLabels { route })
218+
}
219+
}

linkerd/app/inbound/src/metrics.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
pub(crate) mod authz;
1212
pub(crate) mod error;
1313

14-
use crate::http::router::RequestCountFamilies;
14+
use crate::http::router::{RequestCountFamilies, ResponseBodyFamilies};
1515
pub use linkerd_app_core::metrics::*;
1616

1717
/// Holds LEGACY inbound proxy metrics.
@@ -30,6 +30,7 @@ pub struct InboundMetrics {
3030
pub detect: crate::detect::MetricsFamilies,
3131
pub direct: crate::direct::MetricsFamilies,
3232
pub request_count: RequestCountFamilies,
33+
pub response_body_data: ResponseBodyFamilies,
3334
}
3435

3536
impl InboundMetrics {
@@ -40,6 +41,7 @@ impl InboundMetrics {
4041
reg.sub_registry_with_prefix("tcp_transport_header"),
4142
);
4243
let request_count = RequestCountFamilies::register(reg);
44+
let response_body_data = ResponseBodyFamilies::register(reg);
4345

4446
Self {
4547
http_authz: authz::HttpAuthzMetrics::default(),
@@ -50,6 +52,7 @@ impl InboundMetrics {
5052
detect,
5153
direct,
5254
request_count,
55+
response_body_data,
5356
}
5457
}
5558
}

0 commit comments

Comments
 (0)