1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
use std::net::SocketAddr;
use std::time::Duration;

use metrics_util::MetricKindMask;
use rand::prelude::*;

use crate::metrics::prometheus_exporter::PrometheusBuilder;

pub mod metric;
mod prometheus_exporter;
mod worker_proxy;

pub use metric::register_counter;
pub use metric::register_gauge;
pub use metric::Tag;

pub(crate) fn install(addr: SocketAddr, with_proxy: bool) -> anyhow::Result<()> {
    PrometheusBuilder::new()
        .listen_address(addr)
        .idle_timeout(
            MetricKindMask::COUNTER | MetricKindMask::HISTOGRAM,
            Some(Duration::from_secs(10)),
        )
        .install(with_proxy)?;

    Ok(())
}

pub(crate) fn init_metrics(bind_ip: &str, with_proxy: bool) -> Option<SocketAddr> {
    let mut rng = rand::thread_rng();
    let loops = 30;
    for _index in 0..loops {
        let port = rng.gen_range(10000..30000);
        let addr_str = format!("{}:{}", bind_ip, port);
        let addr: SocketAddr = addr_str
            .as_str()
            .parse()
            .expect(format!("failed to parse http listen address {}", addr_str).as_str());

        match install(addr, with_proxy) {
            Ok(_) => {
                info!(
                    "metrics prometheus http exporter listen on http://{}, proxy mode={}",
                    addr.to_string(),
                    with_proxy
                );
                return Some(addr);
            }
            Err(e) => {
                info!("try install PrometheusBuilder on {} failure: {:?}", addr, e);
                continue;
            }
        }
    }

    None
}

#[cfg(test)]
mod tests {
    use crate::metrics::install;

    #[test]
    pub fn install_test() {
        install("127.0.0.1:9000".parse().unwrap(), false).unwrap();
        // install("127.0.0.1:9000".parse().unwrap(), false).unwrap();
        std::thread::sleep(std::time::Duration::from_secs(300000));
    }
}