@@ -10,16 +10,31 @@ 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 > (
1619 request_count : RequestCountFamilies ,
17- // TODO(kate): other metrics families will added here.
18- ) -> impl svc:: Layer < N , Service = NewCountRequests < ExtractRequestCount , N > > {
20+ response_body_metrics : ResponseBodyFamilies ,
21+ ) -> impl svc:: Layer <
22+ N ,
23+ Service = NewCountRequests <
24+ ExtractRequestCount ,
25+ NewRecordBodyData < ExtractRecordBodyDataMetrics , N > ,
26+ > ,
27+ > {
1928 svc:: layer:: mk ( move |inner| {
2029 use svc:: Layer as _;
2130 let extract = ExtractRequestCount ( request_count. clone ( ) ) ;
22- NewCountRequests :: layer_via ( extract) . layer ( inner)
31+
32+ NewCountRequests :: layer_via ( extract) . layer (
33+ NewRecordBodyData :: layer_via ( ExtractRecordBodyDataMetrics (
34+ response_body_metrics. clone ( ) ,
35+ ) )
36+ . layer ( inner) ,
37+ )
2338 } )
2439}
2540
@@ -37,6 +52,20 @@ pub struct RequestCountLabels {
3752#[ derive( Clone , Debug ) ]
3853pub struct ExtractRequestCount ( pub RequestCountFamilies ) ;
3954
55+ #[ derive( Clone , Debug ) ]
56+ pub struct ResponseBodyFamilies {
57+ grpc : linkerd_http_prom:: body_data:: response:: ResponseBodyFamilies < ResponseBodyDataLabels > ,
58+ http : linkerd_http_prom:: body_data:: response:: ResponseBodyFamilies < ResponseBodyDataLabels > ,
59+ }
60+
61+ #[ derive( Clone , Debug , Hash , PartialEq , Eq ) ]
62+ pub struct ResponseBodyDataLabels {
63+ route : RouteLabels ,
64+ }
65+
66+ #[ derive( Clone , Debug ) ]
67+ pub struct ExtractRecordBodyDataMetrics ( ResponseBodyFamilies ) ;
68+
4069// === impl RequestCountFamilies ===
4170
4271impl RequestCountFamilies {
@@ -112,3 +141,79 @@ impl EncodeLabelSet for RequestCountLabels {
112141 self . encode_label_set ( & mut enc)
113142 }
114143}
144+
145+ // === impl ResponseBodyFamilies ===
146+
147+ impl ResponseBodyFamilies {
148+ /// Registers a new [`ResponseBodyDataFamilies`] with the given registry.
149+ pub fn register ( reg : & mut prom:: Registry ) -> Self {
150+ let grpc = {
151+ let reg = reg. sub_registry_with_prefix ( "grpc" ) ;
152+ linkerd_http_prom:: body_data:: response:: ResponseBodyFamilies :: register ( reg)
153+ } ;
154+
155+ let http = {
156+ let reg = reg. sub_registry_with_prefix ( "http" ) ;
157+ linkerd_http_prom:: body_data:: response:: ResponseBodyFamilies :: register ( reg)
158+ } ;
159+
160+ Self { grpc, http }
161+ }
162+
163+ /// Fetches the proper body frame metrics family, given a permitted target.
164+ fn family < T > (
165+ & self ,
166+ permitted : & Permitted < T > ,
167+ ) -> & linkerd_http_prom:: body_data:: response:: ResponseBodyFamilies < ResponseBodyDataLabels > {
168+ let Self { grpc, http } = self ;
169+ match permitted {
170+ Permitted :: Grpc { .. } => grpc,
171+ Permitted :: Http { .. } => http,
172+ }
173+ }
174+ }
175+
176+ // === impl ResponseBodyDataLabels ===
177+
178+ impl EncodeLabelSetMut for ResponseBodyDataLabels {
179+ fn encode_label_set ( & self , enc : & mut LabelSetEncoder < ' _ > ) -> std:: fmt:: Result {
180+ use encoding:: EncodeLabel as _;
181+
182+ let Self {
183+ route :
184+ RouteLabels {
185+ server : ServerLabel ( parent, port) ,
186+ route,
187+ } ,
188+ } = self ;
189+
190+ ( "parent_group" , parent. group ( ) ) . encode ( enc. encode_label ( ) ) ?;
191+ ( "parent_kind" , parent. kind ( ) ) . encode ( enc. encode_label ( ) ) ?;
192+ ( "parent_name" , parent. name ( ) ) . encode ( enc. encode_label ( ) ) ?;
193+ ( "parent_port" , * port) . encode ( enc. encode_label ( ) ) ?;
194+
195+ ( "route_group" , route. group ( ) ) . encode ( enc. encode_label ( ) ) ?;
196+ ( "route_kind" , route. kind ( ) ) . encode ( enc. encode_label ( ) ) ?;
197+ ( "route_name" , route. name ( ) ) . encode ( enc. encode_label ( ) ) ?;
198+
199+ Ok ( ( ) )
200+ }
201+ }
202+
203+ impl EncodeLabelSet for ResponseBodyDataLabels {
204+ fn encode ( & self , mut enc : LabelSetEncoder < ' _ > ) -> std:: fmt:: Result {
205+ self . encode_label_set ( & mut enc)
206+ }
207+ }
208+
209+ // === impl ExtractRecordBodyDataMetrics ===
210+
211+ impl < T > svc:: ExtractParam < BodyDataMetrics , Permitted < T > > for ExtractRecordBodyDataMetrics {
212+ fn extract_param ( & self , permitted : & Permitted < T > ) -> BodyDataMetrics {
213+ let Self ( families) = self ;
214+ let family = families. family ( permitted) ;
215+ let route = permitted. route_labels ( ) ;
216+
217+ family. metrics ( & ResponseBodyDataLabels { route } )
218+ }
219+ }
0 commit comments