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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
use substrate_prometheus_endpoint::{register, Gauge, PrometheusError, Registry, U64};

#[derive(Clone)]
pub enum Metrics {
    Prometheus {
        incoming_connections: Gauge<U64>,
        missing_incoming_connections: Gauge<U64>,
        outgoing_connections: Gauge<U64>,
        missing_outgoing_connections: Gauge<U64>,
    },
    Noop,
}

pub enum Event {
    NewOutgoing,
    NewIncoming,
    DelOutgoing,
    DelIncoming,
    ConnectedOutgoing,
    ConnectedIncoming,
    DisconnectedOutgoing,
    DisconnectedIncoming,
}

impl Metrics {
    pub fn new(registry: Option<Registry>) -> Result<Self, PrometheusError> {
        match registry {
            Some(registry) => Ok(Metrics::Prometheus {
                incoming_connections: register(
                    Gauge::new(
                        "clique_network_incoming_connections",
                        "present incoming connections",
                    )?,
                    &registry,
                )?,
                missing_incoming_connections: register(
                    Gauge::new(
                        "clique_network_missing_incoming_connections",
                        "difference between expected and present incoming connections",
                    )?,
                    &registry,
                )?,
                outgoing_connections: register(
                    Gauge::new(
                        "clique_network_outgoing_connections",
                        "present outgoing connections",
                    )?,
                    &registry,
                )?,
                missing_outgoing_connections: register(
                    Gauge::new(
                        "clique_network_missing_outgoing_connections",
                        "difference between expected and present outgoing connections",
                    )?,
                    &registry,
                )?,
            }),
            None => Ok(Metrics::Noop),
        }
    }

    pub fn noop() -> Self {
        Metrics::Noop
    }

    pub fn report_event(&self, event: Event) {
        use Event::*;
        if let Metrics::Prometheus {
            incoming_connections,
            outgoing_connections,
            missing_incoming_connections,
            missing_outgoing_connections,
        } = self
        {
            match event {
                NewIncoming => missing_incoming_connections.inc(),
                NewOutgoing => missing_outgoing_connections.inc(),
                DelIncoming => missing_incoming_connections.dec(),
                DelOutgoing => missing_outgoing_connections.dec(),
                ConnectedIncoming => {
                    incoming_connections.inc();
                    missing_incoming_connections.dec();
                }
                ConnectedOutgoing => {
                    outgoing_connections.inc();
                    missing_outgoing_connections.dec();
                }
                DisconnectedIncoming => {
                    incoming_connections.dec();
                    missing_incoming_connections.inc();
                }
                DisconnectedOutgoing => {
                    outgoing_connections.dec();
                    missing_outgoing_connections.inc();
                }
            }
        }
    }
}