1
- use anyhow:: Result ;
1
+ use anyhow:: { Error , Result } ;
2
2
use futures_util:: future:: { Future , OptionFuture } ;
3
3
use futures_util:: stream:: Stream ;
4
- use futures_util:: { FutureExt , StreamExt } ;
4
+ use futures_util:: { FutureExt , StreamExt , TryFutureExt } ;
5
5
use hyper:: server:: conn:: Http ;
6
+ use lazy_static:: lazy_static;
6
7
use metrics:: { metrics, metrics_wrapper} ;
8
+ use prometheus:: { register_int_counter_vec, register_int_gauge_vec, IntCounterVec , IntGaugeVec } ;
7
9
use sqlx:: PgPool ;
8
10
use std:: fmt:: Display ;
9
11
use std:: sync:: Arc ;
@@ -20,12 +22,27 @@ mod proxy;
20
22
mod routes;
21
23
mod tls;
22
24
23
- async fn serve < I , S , T , E , R > ( mut io : I , routes : R )
25
+ lazy_static ! {
26
+ static ref TCP_TOTAL_CONNECTION_COUNTER : IntCounterVec = register_int_counter_vec!(
27
+ "tcp_total_connection_counter" ,
28
+ "Sum of TCP Connections" ,
29
+ & [ "endpoint" ]
30
+ )
31
+ . unwrap( ) ;
32
+ static ref TCP_OPEN_CONNECTION_COUNTER : IntGaugeVec = register_int_gauge_vec!(
33
+ "tcp_open_connection_counter" ,
34
+ "Amount of currently open TCP Connections" ,
35
+ & [ "endpoint" ]
36
+ )
37
+ . unwrap( ) ;
38
+ }
39
+
40
+ async fn serve < I , S , T , E , R > ( mut io : I , routes : R , endpoint : & str )
24
41
where
25
42
I : Stream < Item = Result < S , E > > + Unpin + Send ,
26
43
S : Future < Output = Result < T , E > > + Send + ' static ,
27
44
T : AsyncRead + AsyncWrite + Send + Unpin + ' static ,
28
- E : Display ,
45
+ E : Into < Error > + Display + Send ,
29
46
R : Filter < Error = Rejection > + Clone + Send + ' static ,
30
47
R :: Extract : Reply ,
31
48
{
@@ -35,28 +52,28 @@ where
35
52
loop {
36
53
let span = info_span ! ( "conn" , remote. addr = Empty , remote. real = Empty ) ;
37
54
let conn = match io. next ( ) . instrument ( span. clone ( ) ) . await {
38
- Some ( Ok ( conn) ) => conn,
55
+ Some ( Ok ( conn) ) => conn. err_into ( ) ,
39
56
Some ( Err ( err) ) => {
40
57
span. in_scope ( || error ! ( "{}" , err) ) ;
41
58
continue ;
42
59
}
43
60
None => break ,
44
61
} ;
45
62
63
+ TCP_TOTAL_CONNECTION_COUNTER . with_label_values ( & [ endpoint] ) . inc ( ) ;
64
+ let open_counter = TCP_OPEN_CONNECTION_COUNTER . with_label_values ( & [ endpoint] ) ;
65
+ open_counter. inc ( ) ;
66
+
46
67
let http = http. clone ( ) ;
47
68
let service = service. clone ( ) ;
48
69
49
70
tokio:: spawn (
50
71
async move {
51
- let conn = match conn. await {
52
- Ok ( conn) => conn,
53
- Err ( err) => {
54
- error ! ( "{}" , err) ;
55
- return ;
56
- }
57
- } ;
58
- http. serve_connection ( conn, service) . await ;
72
+ let conn = conn. await ?;
73
+ Ok ( http. serve_connection ( conn, service) . await ?)
59
74
}
75
+ . inspect_err ( |err : & Error | error ! ( "{}" , err) )
76
+ . inspect ( move |_| open_counter. dec ( ) )
60
77
. instrument ( span) ,
61
78
) ;
62
79
}
@@ -78,18 +95,18 @@ pub async fn new(
78
95
79
96
let http = http
80
97
. map ( move |http| proxy:: wrap ( http, http_proxy) )
81
- . map ( |http| serve ( http, routes. clone ( ) ) . instrument ( info_span ! ( "HTTP" ) ) )
98
+ . map ( |http| serve ( http, routes. clone ( ) , "HTTP" ) . instrument ( info_span ! ( "HTTP" ) ) )
82
99
. map ( tokio:: spawn) ;
83
100
84
101
let prom = prom
85
102
. map ( move |prom| proxy:: wrap ( prom, prom_proxy) )
86
- . map ( |prom| serve ( prom, metrics ( ) ) . instrument ( info_span ! ( "PROM" ) ) )
103
+ . map ( |prom| serve ( prom, metrics ( ) , "PROM" ) . instrument ( info_span ! ( "PROM" ) ) )
87
104
. map ( tokio:: spawn) ;
88
105
89
106
let https = https
90
107
. map ( move |https| proxy:: wrap ( https, https_proxy) )
91
108
. map ( |https| tls:: wrap ( https, pool) )
92
- . map ( |https| serve ( https, routes) . instrument ( info_span ! ( "HTTPS" ) ) )
109
+ . map ( |https| serve ( https, routes, "HTTPS" ) . instrument ( info_span ! ( "HTTPS" ) ) )
93
110
. map ( tokio:: spawn) ;
94
111
95
112
info ! ( "Starting API" ) ;
0 commit comments