@@ -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
1518pub ( 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 ) ]
4058pub 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
4476impl 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+ }
0 commit comments