1
1
use lazy_static:: lazy_static;
2
- use prometheus:: { register_histogram_vec, Encoder , HistogramTimer , HistogramVec , TextEncoder } ;
2
+ use prometheus:: {
3
+ register_histogram_vec, register_int_counter_vec, Encoder , HistogramTimer , HistogramVec ,
4
+ IntCounterVec , TextEncoder ,
5
+ } ;
3
6
use tracing:: error;
4
- use warp:: filters:: path:: FullPath ;
5
- use warp:: { http:: Response , Filter , Rejection , Reply } ;
7
+ use warp:: filters:: trace;
8
+ use warp:: http:: header:: { HeaderValue , CONTENT_TYPE } ;
9
+ use warp:: http:: { Method , Response } ;
10
+ use warp:: path:: FullPath ;
11
+ use warp:: reply:: Response as WarpResponse ;
12
+ use warp:: { Filter , Rejection , Reply } ;
6
13
14
+ //todo: dont use int maybe
7
15
lazy_static ! {
16
+ static ref HTTP_STATUS_COUNTER : IntCounterVec = register_int_counter_vec!(
17
+ "http_status_counter" ,
18
+ "The HTTP requests status" ,
19
+ & [ "path" , "method" , "status" ]
20
+ )
21
+ . unwrap( ) ;
8
22
static ref HTTP_REQ_HISTOGRAM : HistogramVec = register_histogram_vec!(
9
23
"http_request_duration_seconds" ,
10
24
"The HTTP request latencies in seconds." ,
11
- & [ "path" ]
25
+ & [ "path" , "method" ]
12
26
)
13
27
. unwrap( ) ;
14
28
}
15
29
16
- pub ( super ) fn metrics_wrapper < R : Reply > (
17
- filter : impl Filter < Extract = ( R , ) , Error = Rejection > + Clone + Send + ' static ,
18
- ) -> impl Filter < Extract = ( R , ) , Error = Rejection > + Clone + Send + ' static {
19
- warp:: path:: full ( )
20
- . map ( |path : FullPath | {
21
- HTTP_REQ_HISTOGRAM
22
- . with_label_values ( & [ path. as_str ( ) ] )
23
- . start_timer ( )
24
- } )
25
- . and ( filter)
26
- . map ( |timer : HistogramTimer , res : R | {
27
- timer. observe_duration ( ) ;
28
- //let res = res.into_response();
29
- res
30
- } )
30
+ pub ( super ) trait MetricFn < R , I > : Fn ( I ) -> <Self as MetricFn < R , I > >:: Output
31
+ where
32
+ R : Reply ,
33
+ I : Filter < Extract = ( R , ) , Error = Rejection > ,
34
+ {
35
+ type Output : Filter < Extract = ( WarpResponse , ) , Error = Rejection >
36
+ + Clone
37
+ + Send
38
+ + Sync
39
+ + ' static ;
40
+ }
41
+
42
+ impl < R , I , O , F > MetricFn < R , I > for F
43
+ where
44
+ R : Reply ,
45
+ I : Filter < Extract = ( R , ) , Error = Rejection > + Clone + Send + Sync + ' static ,
46
+ O : Filter < Extract = ( WarpResponse , ) , Error = Rejection > + Clone + Send + Sync + ' static ,
47
+ F : Fn ( I ) -> O ,
48
+ {
49
+ type Output = O ;
50
+ }
51
+
52
+ pub ( super ) fn metrics_wrapper < R , I > ( config : impl Into < Option < & ' static str > > ) -> impl MetricFn < R , I >
53
+ where
54
+ R : Reply ,
55
+ I : Filter < Extract = ( R , ) , Error = Rejection > + Clone + Send + Sync + ' static ,
56
+ {
57
+ let config = config. into ( ) . unwrap_or ( "" ) ;
58
+
59
+ move |filter : I | {
60
+ warp:: filters:: path:: full ( )
61
+ . and ( warp:: filters:: method:: method ( ) )
62
+ . map ( move |path : FullPath , method : Method | {
63
+ let path = match config {
64
+ "" => path. as_str ( ) . to_string ( ) ,
65
+ config => config. to_string ( ) ,
66
+ } ;
67
+ let timer = HTTP_REQ_HISTOGRAM
68
+ . with_label_values ( & [ & path, method. as_str ( ) ] )
69
+ . start_timer ( ) ;
70
+
71
+ ( path, method, timer)
72
+ } )
73
+ . untuple_one ( )
74
+ . and ( filter)
75
+ . map (
76
+ |path : String , method : Method , timer : HistogramTimer , res : R | {
77
+ let res = res. into_response ( ) ;
78
+ HTTP_STATUS_COUNTER
79
+ . with_label_values ( & [ & path, method. as_str ( ) , res. status ( ) . as_str ( ) ] )
80
+ . inc ( ) ;
81
+
82
+ timer. observe_duration ( ) ;
83
+
84
+ res
85
+ } ,
86
+ )
87
+ . with ( trace:: request ( ) )
88
+ . map ( Reply :: into_response)
89
+ }
31
90
}
32
91
33
92
fn request ( ) -> impl Reply {
@@ -43,7 +102,7 @@ fn request() -> impl Reply {
43
102
}
44
103
45
104
Response :: builder ( )
46
- . header ( "Content-Type" , "text/plain" )
105
+ . header ( CONTENT_TYPE , HeaderValue :: from_static ( "text/plain" ) )
47
106
. body ( res)
48
107
. into_response ( )
49
108
}
@@ -53,6 +112,5 @@ pub(super) fn metrics(
53
112
warp:: path ( "metrics" )
54
113
. and ( warp:: get ( ) )
55
114
. map ( request)
56
- . with ( warp:: trace:: request ( ) )
57
- . with ( warp:: wrap_fn ( metrics_wrapper) )
115
+ . with ( warp:: wrap_fn ( metrics_wrapper ( None ) ) )
58
116
}
0 commit comments