@@ -15,8 +15,7 @@ use prometheus_client::{
1515} ;
1616
1717use crate :: api:: v1:: {
18- ApiData ,
19- endpoints:: artifacts:: { ArtifactQuery , OneConfigVersionInfo }
18+ caching:: CacheLabels , endpoints:: artifacts:: { ArtifactQuery , OneConfigVersionInfo } , ApiData
2019} ;
2120
2221/// A macro that automatically initializes and registers a metric using inferred
@@ -37,6 +36,12 @@ macro_rules! make_api_metric {
3736 } ;
3837}
3938
39+ #[ derive( Debug , Hash , PartialEq , Eq , Clone , EncodeLabelSet ) ]
40+ struct ApiRequestLabels {
41+ path : String ,
42+ status_code : u16
43+ }
44+
4045#[ derive( Debug , Hash , PartialEq , Eq , Clone , EncodeLabelSet ) ]
4146struct PlatformAgnosticArtifactLabels {
4247 r#type : String
@@ -47,10 +52,16 @@ struct PlatformAgnosticArtifactLabels {
4752pub struct ApiMetrics {
4853 /// The registry used for storing metrics
4954 registry : Registry ,
55+ /// The generic amount of API requests by path and response code
56+ api_requests : Family < ApiRequestLabels , Counter > ,
5057 /// The amount of OneConfig artifacts requests, by version and loader
5158 oneconfig_artifacts_requests : Family < OneConfigVersionInfo , Counter > ,
5259 /// The amount of platform-agnostic artifacts requests, by type
53- platform_agnostic_artifacts_requests : Family < PlatformAgnosticArtifactLabels , Counter >
60+ platform_agnostic_artifacts_requests : Family < PlatformAgnosticArtifactLabels , Counter > ,
61+ /// The amount of cache hits by endpoint
62+ pub cache_hits : Family < CacheLabels , Counter > ,
63+ /// The amount of cache misses by endpoint
64+ pub cache_misses : Family < CacheLabels , Counter >
5465}
5566
5667/// Configures the metrics endpoint. In addition to this, the metrics middleware
@@ -66,13 +77,19 @@ pub fn configure() -> impl FnOnce(&mut ServiceConfig) {
6677pub fn init_metrics ( ) -> ApiMetrics {
6778 let mut registry = <Registry >:: default ( ) ;
6879
80+ make_api_metric ! ( registry, api_requests) ;
6981 make_api_metric ! ( registry, oneconfig_artifacts_requests) ;
7082 make_api_metric ! ( registry, platform_agnostic_artifacts_requests) ;
83+ make_api_metric ! ( registry, cache_hits) ;
84+ make_api_metric ! ( registry, cache_misses) ;
7185
7286 ApiMetrics {
7387 registry,
88+ api_requests,
7489 oneconfig_artifacts_requests,
75- platform_agnostic_artifacts_requests
90+ platform_agnostic_artifacts_requests,
91+ cache_hits,
92+ cache_misses
7693 }
7794}
7895
@@ -96,37 +113,50 @@ pub async fn middleware(
96113 mut service_request : ServiceRequest ,
97114 next : Next < impl MessageBody >
98115) -> Result < ServiceResponse < impl MessageBody > , actix_web:: Error > {
99- if let Some ( pattern) = service_request. match_pattern ( ) {
100- let data = service_request. extract :: < web:: Data < ApiData > > ( ) . await ?;
101-
102- match pattern. as_str ( ) {
103- "/v1/artifacts/oneconfig" => {
104- data. metrics
105- . oneconfig_artifacts_requests
106- . get_or_create (
107- & service_request
108- . extract :: < web:: Query < ArtifactQuery < OneConfigVersionInfo > > > ( )
109- . await ?
110- . version_info
111- )
112- . inc ( ) ;
113- }
114- "/v1/artifacts/{artifact:stage1|relaunch}" => {
115- data. metrics
116- . platform_agnostic_artifacts_requests
117- . get_or_create ( & PlatformAgnosticArtifactLabels {
118- // Unfortunately actix makes it difficult to extract the real
119- // parsed URL parameter, so just substring instead as a substitute
120- r#type : service_request. uri ( ) . path ( )
121- [ const { "/v1/artifacts/" . len ( ) } ..]
122- . to_string ( )
123- } )
124- . inc ( ) ;
125- }
126- _ => ( )
127- } ;
128- }
116+ let data = service_request. extract :: < web:: Data < ApiData > > ( ) . await ?;
117+
118+ match service_request. match_pattern ( ) . unwrap_or ( "default" . to_string ( ) ) . as_str ( ) {
119+ "/v1/artifacts/oneconfig" => {
120+ data. metrics
121+ . oneconfig_artifacts_requests
122+ . get_or_create (
123+ & service_request
124+ . extract :: < web:: Query < ArtifactQuery < OneConfigVersionInfo > > > ( )
125+ . await ?
126+ . version_info
127+ )
128+ . inc ( ) ;
129+ }
130+ "/v1/artifacts/{artifact:stage1|relaunch}" => {
131+ data. metrics
132+ . platform_agnostic_artifacts_requests
133+ . get_or_create ( & PlatformAgnosticArtifactLabels {
134+ // Unfortunately actix makes it difficult to extract the real
135+ // parsed URL parameter, so just substring instead as a substitute
136+ r#type : service_request. uri ( ) . path ( )
137+ [ const { "/v1/artifacts/" . len ( ) } ..]
138+ . to_string ( )
139+ } )
140+ . inc ( ) ;
141+ }
142+ _ => ( )
143+ } ;
129144
130145 // Let the real request handler continue
131- return next. call ( service_request) . await ;
146+ let path = service_request. uri ( ) . path ( ) . to_string ( ) ;
147+ let response = next. call ( service_request) . await ;
148+
149+ let labels = match & response {
150+ Ok ( r) => ApiRequestLabels {
151+ path,
152+ status_code : r. status ( ) . as_u16 ( )
153+ } ,
154+ Err ( e) => ApiRequestLabels {
155+ path,
156+ status_code : e. as_response_error ( ) . status_code ( ) . as_u16 ( )
157+ }
158+ } ;
159+ data. metrics . api_requests . get_or_create ( & labels) . inc ( ) ;
160+
161+ response
132162}
0 commit comments