1
1
use std:: io:: { Read , Write } ;
2
2
use std:: net:: { TcpListener , TcpStream } ;
3
+ use std:: sync:: RwLock ;
3
4
use std:: thread;
4
5
5
- use prometheus:: { Encoder , IntCounterVec , Opts , Registry } ;
6
+ use prometheus_client:: encoding:: text:: encode;
7
+ use prometheus_client:: encoding:: EncodeLabelSet ;
8
+ use prometheus_client:: metrics:: counter:: Counter ;
9
+ use prometheus_client:: metrics:: family:: Family ;
10
+ use prometheus_client:: registry:: { Metric , Registry } ;
11
+
12
+ #[ derive( Clone , Hash , PartialEq , Eq , EncodeLabelSet , Debug ) ]
13
+ struct UdpLabels {
14
+ server : String ,
15
+ r#type : String ,
16
+ }
6
17
7
18
lazy_static ! {
8
- static ref REGISTRY : Registry = Registry :: new( ) ;
19
+ static ref REGISTRY : RwLock < Registry > = RwLock :: new( < Registry > :: default ( ) ) ;
9
20
10
21
// UDP sent
11
- static ref UDP_SENT_COUNT : IntCounterVec = IntCounterVec :: new( Opts :: new( "udp_sent_count" , "Number of UDP datagrams sent" ) , & [ "server" , "type" ] ) . unwrap( ) ;
12
- static ref UDP_SENT_BYTES : IntCounterVec = IntCounterVec :: new( Opts :: new( "udp_sent_bytes" , "Number of bytes sent over UDP" ) , & [ "server" , "type" ] ) . unwrap( ) ;
22
+ static ref UDP_SENT_COUNT : Family <UdpLabels , Counter > = {
23
+ let counter = Family :: <UdpLabels , Counter >:: default ( ) ;
24
+ register( "udp_sent_count" , "Number of UDP datagrams sent" , counter. clone( ) ) ;
25
+ counter
26
+ } ;
27
+ static ref UDP_SENT_BYTES : Family <UdpLabels , Counter > = {
28
+ let counter = Family :: <UdpLabels , Counter >:: default ( ) ;
29
+ register( "udp_sent_bytes" , "Number of bytes sent over UDP" , counter. clone( ) ) ;
30
+ counter
31
+ } ;
32
+
13
33
14
34
// UDP received
15
- static ref UDP_RECEIVED_COUNT : IntCounterVec = IntCounterVec :: new( Opts :: new( "udp_received_count" , "Number of UDP datagrams received" ) , & [ "server" , "type" ] ) . unwrap( ) ;
16
- static ref UDP_RECEIVED_BYTES : IntCounterVec = IntCounterVec :: new( Opts :: new( "udp_received_bytes" , "Number of bytes received over UDP" ) , & [ "server" , "type" ] ) . unwrap( ) ;
35
+ static ref UDP_RECEIVED_COUNT : Family <UdpLabels , Counter > = {
36
+ let counter = Family :: <UdpLabels , Counter >:: default ( ) ;
37
+ register( "udp_received_count" , "Number of UDP datagrams received" , counter. clone( ) ) ;
38
+ counter
39
+ } ;
40
+ static ref UDP_RECEIVED_BYTES : Family <UdpLabels , Counter > = {
41
+ let counter = Family :: <UdpLabels , Counter >:: default ( ) ;
42
+ register( "udp_received_bytes" , "Number of bytes received over UDP" , counter. clone( ) ) ;
43
+ counter
44
+ } ;
17
45
}
18
46
19
- pub fn start ( bind : String ) {
20
- debug ! ( "Registering Prometheus metrics" ) ;
21
- REGISTRY . register ( Box :: new ( UDP_SENT_COUNT . clone ( ) ) ) . unwrap ( ) ;
22
- REGISTRY . register ( Box :: new ( UDP_SENT_BYTES . clone ( ) ) ) . unwrap ( ) ;
23
- REGISTRY
24
- . register ( Box :: new ( UDP_RECEIVED_COUNT . clone ( ) ) )
25
- . unwrap ( ) ;
26
- REGISTRY
27
- . register ( Box :: new ( UDP_RECEIVED_BYTES . clone ( ) ) )
28
- . unwrap ( ) ;
47
+ fn register ( name : & str , help : & str , metric : impl Metric ) {
48
+ let mut registry_w = REGISTRY . write ( ) . unwrap ( ) ;
49
+ registry_w. register ( name, help, metric)
50
+ }
29
51
52
+ pub fn start ( bind : String ) {
30
53
info ! ( "Starting Prometheus metrics server, bind: {}" , bind) ;
31
54
let listener = TcpListener :: bind ( bind) . expect ( "bind metrics server error" ) ;
32
55
@@ -43,22 +66,38 @@ pub fn start(bind: String) {
43
66
}
44
67
45
68
pub fn incr_udp_sent_count ( server : & str , typ : & str ) {
46
- UDP_SENT_COUNT . with_label_values ( & [ server, typ] ) . inc ( ) ;
69
+ UDP_SENT_COUNT
70
+ . get_or_create ( & UdpLabels {
71
+ server : server. to_string ( ) ,
72
+ r#type : typ. to_string ( ) ,
73
+ } )
74
+ . inc ( ) ;
47
75
}
48
76
49
77
pub fn incr_udp_sent_bytes ( server : & str , typ : & str , count : usize ) {
50
78
UDP_SENT_BYTES
51
- . with_label_values ( & [ server, typ] )
79
+ . get_or_create ( & UdpLabels {
80
+ server : server. to_string ( ) ,
81
+ r#type : typ. to_string ( ) ,
82
+ } )
52
83
. inc_by ( count as u64 ) ;
53
84
}
54
85
55
86
pub fn incr_udp_received_count ( server : & str , typ : & str ) {
56
- UDP_RECEIVED_COUNT . with_label_values ( & [ server, typ] ) . inc ( ) ;
87
+ UDP_RECEIVED_COUNT
88
+ . get_or_create ( & UdpLabels {
89
+ server : server. to_string ( ) ,
90
+ r#type : typ. to_string ( ) ,
91
+ } )
92
+ . inc ( ) ;
57
93
}
58
94
59
95
pub fn incr_udp_received_bytes ( server : & str , typ : & str , count : usize ) {
60
96
UDP_RECEIVED_BYTES
61
- . with_label_values ( & [ server, typ] )
97
+ . get_or_create ( & UdpLabels {
98
+ server : server. to_string ( ) ,
99
+ r#type : typ. to_string ( ) ,
100
+ } )
62
101
. inc_by ( count as u64 ) ;
63
102
}
64
103
@@ -73,21 +112,21 @@ fn handle_read(mut stream: &TcpStream) {
73
112
}
74
113
75
114
fn handle_write ( mut stream : TcpStream ) {
76
- let encoder = prometheus:: TextEncoder :: new ( ) ;
77
115
if let Err ( err) =
78
116
stream. write ( b"HTTP/1.1 200 OK\r \n Content-Type: text/plain; charset=UTF-8\r \n \r \n " )
79
117
{
80
118
error ! ( "Write http header error: {}" , err) ;
81
119
return ;
82
120
} ;
83
121
84
- let mut buffer = Vec :: new ( ) ;
85
- if let Err ( err) = encoder. encode ( & REGISTRY . gather ( ) , & mut buffer) {
86
- error ! ( "Encode Prometheus metrics error: {}" , err) ;
122
+ let registry_r = REGISTRY . read ( ) . unwrap ( ) ;
123
+ let mut buffer = String :: new ( ) ;
124
+ if let Err ( e) = encode ( & mut buffer, & registry_r) {
125
+ error ! ( "Encode Prometheus metrics error: {}" , e) ;
87
126
return ;
88
127
}
89
128
90
- if let Err ( err) = stream. write ( & buffer) {
129
+ if let Err ( err) = stream. write ( buffer. as_bytes ( ) ) {
91
130
error ! ( "Write metrics error: {}" , err) ;
92
131
} ;
93
132
}
0 commit comments