Skip to content

Commit e8bb635

Browse files
committed
feat(app/inbound): request body frame size metrics
this commit introduces an additional layer of telemetry to the inbound proxy's http router. either http and grpc metrics are used, depending upon the policy that authorized a given request. this is based upon #4174, which refactored the request body telemetry middleware to be metrics agnostic. see: * #4165 * #4166 * #4174 * #4127 Signed-off-by: katelyn martin <[email protected]>
1 parent 8a313b9 commit e8bb635

File tree

2 files changed

+128
-3
lines changed

2 files changed

+128
-3
lines changed

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

Lines changed: 124 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,22 @@ use linkerd_http_prom::{
1818
pub(super) fn layer<N>(
1919
InboundMetrics {
2020
request_count,
21+
request_body_data,
2122
response_body_data,
2223
..
2324
}: &InboundMetrics,
2425
) -> impl svc::Layer<
2526
N,
2627
Service = NewCountRequests<
2728
ExtractRequestCount,
28-
NewRecordBodyData<ExtractRecordBodyDataMetrics, N>,
29+
NewRecordBodyData<
30+
ExtractRecordBodyDataMetrics,
31+
linkerd_http_prom::body_data::request::NewRecordBodyData<
32+
N,
33+
ExtractRequestBodyDataParams,
34+
ExtractRequestBodyDataMetrics,
35+
>,
36+
>,
2937
>,
3038
> {
3139
use svc::Layer as _;
@@ -40,7 +48,12 @@ pub(super) fn layer<N>(
4048
NewRecordBodyData::layer_via(extract)
4149
};
4250

43-
svc::layer::mk(move |inner| count.layer(body.layer(inner)))
51+
let request = {
52+
let extract = ExtractRequestBodyDataParams(request_body_data.clone());
53+
linkerd_http_prom::body_data::request::NewRecordBodyData::new(extract)
54+
};
55+
56+
svc::layer::mk(move |inner| count.layer(body.layer(request.layer(inner))))
4457
}
4558

4659
#[derive(Clone, Debug)]
@@ -71,6 +84,23 @@ pub struct ResponseBodyDataLabels {
7184
#[derive(Clone, Debug)]
7285
pub struct ExtractRecordBodyDataMetrics(ResponseBodyFamilies);
7386

87+
#[derive(Clone, Debug)]
88+
pub struct RequestBodyFamilies {
89+
grpc: linkerd_http_prom::body_data::request::RequestBodyFamilies<RequestBodyDataLabels>,
90+
http: linkerd_http_prom::body_data::request::RequestBodyFamilies<RequestBodyDataLabels>,
91+
}
92+
93+
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
94+
pub struct RequestBodyDataLabels {
95+
route: RouteLabels,
96+
}
97+
98+
#[derive(Clone, Debug)]
99+
pub struct ExtractRequestBodyDataParams(RequestBodyFamilies);
100+
101+
#[derive(Clone, Debug)]
102+
pub struct ExtractRequestBodyDataMetrics(BodyDataMetrics);
103+
74104
// === impl RequestCountFamilies ===
75105

76106
impl RequestCountFamilies {
@@ -232,3 +262,95 @@ where
232262
family.metrics(&ResponseBodyDataLabels { route })
233263
}
234264
}
265+
266+
// === impl RequestBodyFamilies ===
267+
268+
impl RequestBodyFamilies {
269+
/// Registers a new [`RequestBodyDataFamilies`] with the given registry.
270+
pub fn register(reg: &mut prom::Registry) -> Self {
271+
let grpc = {
272+
let reg = reg.sub_registry_with_prefix("grpc");
273+
linkerd_http_prom::body_data::request::RequestBodyFamilies::register(reg)
274+
};
275+
276+
let http = {
277+
let reg = reg.sub_registry_with_prefix("http");
278+
linkerd_http_prom::body_data::request::RequestBodyFamilies::register(reg)
279+
};
280+
281+
Self { grpc, http }
282+
}
283+
284+
/// Fetches the proper body frame metrics family, given a permitted target.
285+
fn family(
286+
&self,
287+
variant: PermitVariant,
288+
) -> &linkerd_http_prom::body_data::request::RequestBodyFamilies<RequestBodyDataLabels> {
289+
let Self { grpc, http } = self;
290+
match variant {
291+
PermitVariant::Grpc => grpc,
292+
PermitVariant::Http => http,
293+
}
294+
}
295+
}
296+
297+
// === impl RequestBodyDataLabels ===
298+
299+
impl EncodeLabelSetMut for RequestBodyDataLabels {
300+
fn encode_label_set(&self, enc: &mut LabelSetEncoder<'_>) -> std::fmt::Result {
301+
use encoding::EncodeLabel as _;
302+
303+
let Self {
304+
route:
305+
RouteLabels {
306+
server: ServerLabel(parent, port),
307+
route,
308+
},
309+
} = self;
310+
311+
("parent_group", parent.group()).encode(enc.encode_label())?;
312+
("parent_kind", parent.kind()).encode(enc.encode_label())?;
313+
("parent_name", parent.name()).encode(enc.encode_label())?;
314+
("parent_port", *port).encode(enc.encode_label())?;
315+
316+
("route_group", route.group()).encode(enc.encode_label())?;
317+
("route_kind", route.kind()).encode(enc.encode_label())?;
318+
("route_name", route.name()).encode(enc.encode_label())?;
319+
320+
Ok(())
321+
}
322+
}
323+
324+
impl EncodeLabelSet for RequestBodyDataLabels {
325+
fn encode(&self, mut enc: LabelSetEncoder<'_>) -> std::fmt::Result {
326+
self.encode_label_set(&mut enc)
327+
}
328+
}
329+
330+
// === impl ExtractRequestBodyDataParams ===
331+
332+
impl<T> svc::ExtractParam<ExtractRequestBodyDataMetrics, T> for ExtractRequestBodyDataParams
333+
where
334+
T: svc::Param<PermitVariant> + svc::Param<RouteLabels>,
335+
{
336+
fn extract_param(&self, target: &T) -> ExtractRequestBodyDataMetrics {
337+
let Self(families) = self;
338+
let variant = target.param();
339+
let route = target.param();
340+
341+
let family = families.family(variant);
342+
let metrics = family.metrics(&RequestBodyDataLabels { route });
343+
344+
ExtractRequestBodyDataMetrics(metrics)
345+
}
346+
}
347+
348+
// === impl ExtractRequestBodyDataMetrics ===
349+
350+
impl<T> svc::ExtractParam<BodyDataMetrics, T> for ExtractRequestBodyDataMetrics {
351+
fn extract_param(&self, _: &T) -> BodyDataMetrics {
352+
let Self(metrics) = self;
353+
354+
metrics.clone()
355+
}
356+
}

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, ResponseBodyFamilies};
14+
use crate::http::router::{RequestBodyFamilies, 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 request_body_data: RequestBodyFamilies,
3334
pub response_body_data: ResponseBodyFamilies,
3435
}
3536

@@ -41,6 +42,7 @@ impl InboundMetrics {
4142
reg.sub_registry_with_prefix("tcp_transport_header"),
4243
);
4344
let request_count = RequestCountFamilies::register(reg);
45+
let request_body_data = RequestBodyFamilies::register(reg);
4446
let response_body_data = ResponseBodyFamilies::register(reg);
4547

4648
Self {
@@ -52,6 +54,7 @@ impl InboundMetrics {
5254
detect,
5355
direct,
5456
request_count,
57+
request_body_data,
5558
response_body_data,
5659
}
5760
}

0 commit comments

Comments
 (0)