Skip to content

Commit 402ab4a

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 13220e8 commit 402ab4a

File tree

2 files changed

+124
-3
lines changed

2 files changed

+124
-3
lines changed

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

Lines changed: 120 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 {
@@ -222,3 +252,91 @@ impl<T> svc::ExtractParam<BodyDataMetrics, Permitted<T>> for ExtractRecordBodyDa
222252
family.metrics(&ResponseBodyDataLabels { route })
223253
}
224254
}
255+
256+
// === impl RequestBodyFamilies ===
257+
258+
impl RequestBodyFamilies {
259+
/// Registers a new [`RequestBodyDataFamilies`] with the given registry.
260+
pub fn register(reg: &mut prom::Registry) -> Self {
261+
let grpc = {
262+
let reg = reg.sub_registry_with_prefix("grpc");
263+
linkerd_http_prom::body_data::request::RequestBodyFamilies::register(reg)
264+
};
265+
266+
let http = {
267+
let reg = reg.sub_registry_with_prefix("http");
268+
linkerd_http_prom::body_data::request::RequestBodyFamilies::register(reg)
269+
};
270+
271+
Self { grpc, http }
272+
}
273+
274+
/// Fetches the proper body frame metrics family, given a permitted target.
275+
fn family<T>(
276+
&self,
277+
permitted: &Permitted<T>,
278+
) -> &linkerd_http_prom::body_data::request::RequestBodyFamilies<RequestBodyDataLabels> {
279+
let Self { grpc, http } = self;
280+
match permitted {
281+
Permitted::Grpc { .. } => grpc,
282+
Permitted::Http { .. } => http,
283+
}
284+
}
285+
}
286+
287+
// === impl RequestBodyDataLabels ===
288+
289+
impl EncodeLabelSetMut for RequestBodyDataLabels {
290+
fn encode_label_set(&self, enc: &mut LabelSetEncoder<'_>) -> std::fmt::Result {
291+
use encoding::EncodeLabel as _;
292+
293+
let Self {
294+
route:
295+
RouteLabels {
296+
server: ServerLabel(parent, port),
297+
route,
298+
},
299+
} = self;
300+
301+
("parent_group", parent.group()).encode(enc.encode_label())?;
302+
("parent_kind", parent.kind()).encode(enc.encode_label())?;
303+
("parent_name", parent.name()).encode(enc.encode_label())?;
304+
("parent_port", *port).encode(enc.encode_label())?;
305+
306+
("route_group", route.group()).encode(enc.encode_label())?;
307+
("route_kind", route.kind()).encode(enc.encode_label())?;
308+
("route_name", route.name()).encode(enc.encode_label())?;
309+
310+
Ok(())
311+
}
312+
}
313+
314+
impl EncodeLabelSet for RequestBodyDataLabels {
315+
fn encode(&self, mut enc: LabelSetEncoder<'_>) -> std::fmt::Result {
316+
self.encode_label_set(&mut enc)
317+
}
318+
}
319+
320+
// === impl ExtractRequestBodyDataParams ===
321+
322+
impl<T> svc::ExtractParam<ExtractRequestBodyDataMetrics, Permitted<T>>
323+
for ExtractRequestBodyDataParams
324+
{
325+
fn extract_param(&self, permitted: &Permitted<T>) -> ExtractRequestBodyDataMetrics {
326+
let Self(families) = self;
327+
let family = families.family(permitted);
328+
let route = permitted.route_labels();
329+
let metrics = family.metrics(&RequestBodyDataLabels { route });
330+
ExtractRequestBodyDataMetrics(metrics)
331+
}
332+
}
333+
334+
// === impl ExtractRequestBodyDataMetrics ===
335+
336+
impl<T> svc::ExtractParam<BodyDataMetrics, T> for ExtractRequestBodyDataMetrics {
337+
fn extract_param(&self, _: &T) -> BodyDataMetrics {
338+
let Self(metrics) = self;
339+
340+
metrics.clone()
341+
}
342+
}

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)