@@ -18,6 +18,7 @@ use linkerd_http_prom::{
1818pub ( super ) fn layer < N > (
1919 InboundMetrics {
2020 request_count,
21+ request_body_data,
2122 response_body_data,
2223 ..
2324 } : & InboundMetrics ,
@@ -34,11 +35,16 @@ pub(super) fn layer<N>(
3435 NewRecordResponseBodyData :: layer_via ( extract)
3536 } ;
3637
37- svc:: layer:: mk ( move |inner| count. layer ( body. layer ( inner) ) )
38+ let request = {
39+ let extract = ExtractRequestBodyDataParams ( request_body_data. clone ( ) ) ;
40+ NewRecordRequestBodyData :: new ( extract)
41+ } ;
42+
43+ svc:: layer:: mk ( move |inner| count. layer ( body. layer ( request. layer ( inner) ) ) )
3844}
3945
4046/// An `N`-typed service instrumented with metrics middleware.
41- type Instrumented < N > = NewCountRequests < NewRecordResponseBodyData < N > > ;
47+ type Instrumented < N > = NewCountRequests < NewRecordResponseBodyData < NewRecordRequestBodyData < N > > > ;
4248
4349/// An `N`-typed `NewService<T>` instrumented with request counting metrics.
4450type NewCountRequests < N > = count_reqs:: NewCountRequests < ExtractRequestCount , N > ;
@@ -75,6 +81,30 @@ pub struct ResponseBodyDataLabels {
7581#[ derive( Clone , Debug ) ]
7682pub struct ExtractResponseBodyDataMetrics ( ResponseBodyFamilies ) ;
7783
84+ /// An `N`-typed `NewService<T>` instrumented with request body metrics.
85+ type NewRecordRequestBodyData < N > = body_data:: request:: NewRecordBodyData <
86+ N ,
87+ ExtractRequestBodyDataParams ,
88+ ExtractRequestBodyDataMetrics ,
89+ > ;
90+
91+ #[ derive( Clone , Debug ) ]
92+ pub struct RequestBodyFamilies {
93+ grpc : body_data:: request:: RequestBodyFamilies < RequestBodyDataLabels > ,
94+ http : body_data:: request:: RequestBodyFamilies < RequestBodyDataLabels > ,
95+ }
96+
97+ #[ derive( Clone , Debug , Hash , PartialEq , Eq ) ]
98+ pub struct RequestBodyDataLabels {
99+ route : RouteLabels ,
100+ }
101+
102+ #[ derive( Clone , Debug ) ]
103+ pub struct ExtractRequestBodyDataParams ( RequestBodyFamilies ) ;
104+
105+ #[ derive( Clone , Debug ) ]
106+ pub struct ExtractRequestBodyDataMetrics ( BodyDataMetrics ) ;
107+
78108// === impl RequestCountFamilies ===
79109
80110impl RequestCountFamilies {
@@ -236,3 +266,95 @@ where
236266 family. metrics ( & ResponseBodyDataLabels { route } )
237267 }
238268}
269+
270+ // === impl RequestBodyFamilies ===
271+
272+ impl RequestBodyFamilies {
273+ /// Registers a new [`RequestBodyDataFamilies`] with the given registry.
274+ pub fn register ( reg : & mut prom:: Registry ) -> Self {
275+ let grpc = {
276+ let reg = reg. sub_registry_with_prefix ( "grpc" ) ;
277+ body_data:: request:: RequestBodyFamilies :: register ( reg)
278+ } ;
279+
280+ let http = {
281+ let reg = reg. sub_registry_with_prefix ( "http" ) ;
282+ body_data:: request:: RequestBodyFamilies :: register ( reg)
283+ } ;
284+
285+ Self { grpc, http }
286+ }
287+
288+ /// Fetches the proper body frame metrics family, given a permitted target.
289+ fn family (
290+ & self ,
291+ variant : PermitVariant ,
292+ ) -> & body_data:: request:: RequestBodyFamilies < RequestBodyDataLabels > {
293+ let Self { grpc, http } = self ;
294+ match variant {
295+ PermitVariant :: Grpc => grpc,
296+ PermitVariant :: Http => http,
297+ }
298+ }
299+ }
300+
301+ // === impl RequestBodyDataLabels ===
302+
303+ impl EncodeLabelSetMut for RequestBodyDataLabels {
304+ fn encode_label_set ( & self , enc : & mut LabelSetEncoder < ' _ > ) -> std:: fmt:: Result {
305+ use encoding:: EncodeLabel as _;
306+
307+ let Self {
308+ route :
309+ RouteLabels {
310+ server : ServerLabel ( parent, port) ,
311+ route,
312+ } ,
313+ } = self ;
314+
315+ ( "parent_group" , parent. group ( ) ) . encode ( enc. encode_label ( ) ) ?;
316+ ( "parent_kind" , parent. kind ( ) ) . encode ( enc. encode_label ( ) ) ?;
317+ ( "parent_name" , parent. name ( ) ) . encode ( enc. encode_label ( ) ) ?;
318+ ( "parent_port" , * port) . encode ( enc. encode_label ( ) ) ?;
319+
320+ ( "route_group" , route. group ( ) ) . encode ( enc. encode_label ( ) ) ?;
321+ ( "route_kind" , route. kind ( ) ) . encode ( enc. encode_label ( ) ) ?;
322+ ( "route_name" , route. name ( ) ) . encode ( enc. encode_label ( ) ) ?;
323+
324+ Ok ( ( ) )
325+ }
326+ }
327+
328+ impl EncodeLabelSet for RequestBodyDataLabels {
329+ fn encode ( & self , mut enc : LabelSetEncoder < ' _ > ) -> std:: fmt:: Result {
330+ self . encode_label_set ( & mut enc)
331+ }
332+ }
333+
334+ // === impl ExtractRequestBodyDataParams ===
335+
336+ impl < T > svc:: ExtractParam < ExtractRequestBodyDataMetrics , T > for ExtractRequestBodyDataParams
337+ where
338+ T : svc:: Param < PermitVariant > + svc:: Param < RouteLabels > ,
339+ {
340+ fn extract_param ( & self , target : & T ) -> ExtractRequestBodyDataMetrics {
341+ let Self ( families) = self ;
342+ let variant = target. param ( ) ;
343+ let route = target. param ( ) ;
344+
345+ let family = families. family ( variant) ;
346+ let metrics = family. metrics ( & RequestBodyDataLabels { route } ) ;
347+
348+ ExtractRequestBodyDataMetrics ( metrics)
349+ }
350+ }
351+
352+ // === impl ExtractRequestBodyDataMetrics ===
353+
354+ impl < T > svc:: ExtractParam < BodyDataMetrics , T > for ExtractRequestBodyDataMetrics {
355+ fn extract_param ( & self , _: & T ) -> BodyDataMetrics {
356+ let Self ( metrics) = self ;
357+
358+ metrics. clone ( )
359+ }
360+ }
0 commit comments