Skip to content

Commit d094b1f

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. NB: this is based upon <#4165> Signed-off-by: katelyn martin <[email protected]>
1 parent 2e7c205 commit d094b1f

File tree

3 files changed

+117
-6
lines changed

3 files changed

+117
-6
lines changed

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

Lines changed: 1 addition & 1 deletion
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

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

Lines changed: 112 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,37 @@ 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>(
16-
InboundMetrics { request_count, .. }: &InboundMetrics,
17-
) -> impl svc::Layer<N, Service = NewCountRequests<ExtractRequestCount, N>> {
19+
InboundMetrics {
20+
request_count,
21+
response_body_data,
22+
..
23+
}: &InboundMetrics,
24+
) -> impl svc::Layer<
25+
N,
26+
Service = NewCountRequests<
27+
ExtractRequestCount,
28+
NewRecordBodyData<ExtractRecordBodyDataMetrics, N>,
29+
>,
30+
> {
1831
use svc::Layer as _;
1932

2033
let count = {
2134
let extract = ExtractRequestCount(request_count.clone());
2235
NewCountRequests::layer_via(extract)
2336
};
2437

25-
svc::layer::mk(move |inner| count.layer(inner))
38+
let body = {
39+
let extract = ExtractRecordBodyDataMetrics(response_body_data.clone());
40+
NewRecordBodyData::layer_via(extract)
41+
};
42+
43+
svc::layer::mk(move |inner| count.layer(body.layer(inner)))
2644
}
2745

2846
#[derive(Clone, Debug)]
@@ -39,6 +57,20 @@ pub struct RequestCountLabels {
3957
#[derive(Clone, Debug)]
4058
pub struct ExtractRequestCount(pub RequestCountFamilies);
4159

60+
#[derive(Clone, Debug)]
61+
pub struct ResponseBodyFamilies {
62+
grpc: linkerd_http_prom::body_data::response::ResponseBodyFamilies<ResponseBodyDataLabels>,
63+
http: linkerd_http_prom::body_data::response::ResponseBodyFamilies<ResponseBodyDataLabels>,
64+
}
65+
66+
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
67+
pub struct ResponseBodyDataLabels {
68+
route: RouteLabels,
69+
}
70+
71+
#[derive(Clone, Debug)]
72+
pub struct ExtractRecordBodyDataMetrics(ResponseBodyFamilies);
73+
4274
// === impl RequestCountFamilies ===
4375

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

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)