libp2p_scatter/
metrics.rs1use std::collections::HashMap;
2
3use prometheus_client::metrics::counter::Counter;
4use prometheus_client::metrics::family::Family;
5use prometheus_client::metrics::gauge::Gauge;
6use prometheus_client::registry::Registry;
7
8use crate::Topic;
9
10pub struct Metrics {
11 topic_info: HashMap<Topic, EverSubscribed>,
13 topic_subscription_status: Family<Topic, Gauge>,
16 topic_peers_count: Family<Topic, Gauge>,
19
20 topic_msg_sent_counts: Family<Topic, Counter>,
22 topic_msg_sent_bytes: Family<Topic, Counter>,
24 topic_msg_published: Family<Topic, Counter>,
26
27 topic_msg_recv_counts: Family<Topic, Counter>,
29 topic_msg_recv_bytes: Family<Topic, Counter>,
31}
32
33type EverSubscribed = bool;
34
35impl Metrics {
36 pub fn new(registry: &mut Registry) -> Self {
37 macro_rules! register_family {
38 ($name:expr, $help:expr) => {{
39 let fam = Family::default();
40 registry.register($name, $help, fam.clone());
41 fam
42 }};
43 }
44
45 let topic_subscription_status = register_family!(
46 "topic_subscription_status",
47 "Subscription status per known topic"
48 );
49
50 let topic_peers_count = register_family!(
51 "topic_peers_counts",
52 "Number of peers subscribed to each topic"
53 );
54
55 let topic_msg_sent_counts = register_family!(
56 "topic_msg_sent_counts",
57 "Number of gossip messages sent to each topic"
58 );
59 let topic_msg_published = register_family!(
60 "topic_msg_published",
61 "Number of gossip messages published to each topic"
62 );
63 let topic_msg_sent_bytes = register_family!(
64 "topic_msg_sent_bytes",
65 "Bytes from gossip messages sent to each topic"
66 );
67
68 let topic_msg_recv_counts = register_family!(
69 "topic_msg_recv_counts",
70 "Number of gossip messages received on each topic"
71 );
72 let topic_msg_recv_bytes = register_family!(
73 "topic_msg_recv_bytes",
74 "Bytes received from gossip messages for each topic"
75 );
76
77 Self {
78 topic_info: HashMap::new(),
79 topic_subscription_status,
80 topic_peers_count,
81 topic_msg_sent_counts,
82 topic_msg_published,
83 topic_msg_sent_bytes,
84 topic_msg_recv_counts,
85 topic_msg_recv_bytes,
86 }
87 }
88
89 fn register_topic(&mut self, topic: &Topic) {
91 if !self.topic_info.contains_key(topic) {
92 self.topic_info.entry(*topic).or_insert(false);
93 self.topic_subscription_status.get_or_create(topic).set(0);
94 }
95 }
96
97 pub(crate) fn subscribe(&mut self, topic: &Topic) {
98 self.register_topic(topic);
99 self.topic_info.entry(*topic).or_insert(false);
100 self.topic_subscription_status.get_or_create(topic).set(1);
101 }
102
103 pub(crate) fn unsubscribe(&mut self, topic: &Topic) {
104 self.register_topic(topic);
105 self.topic_subscription_status.get_or_create(topic).set(0);
106 }
107
108 pub(crate) fn inc_topic_peers(&mut self, topic: &Topic) {
110 self.register_topic(topic);
111 self.topic_peers_count.get_or_create(topic).inc();
112 }
113
114 pub(crate) fn dec_topic_peers(&mut self, topic: &Topic) {
116 self.register_topic(topic);
117 self.topic_peers_count.get_or_create(topic).dec();
118 }
119
120 pub(crate) fn register_published_message(&mut self, topic: &Topic) {
121 self.register_topic(topic);
122 self.topic_msg_published.get_or_create(topic).inc();
123 }
124
125 pub(crate) fn msg_sent(&mut self, topic: &Topic, bytes: usize) {
127 self.register_topic(topic);
128 self.topic_msg_sent_counts.get_or_create(topic).inc();
129 self.topic_msg_sent_bytes
130 .get_or_create(topic)
131 .inc_by(bytes as u64);
132 }
133
134 pub(crate) fn msg_received(&mut self, topic: &Topic, bytes: usize) {
136 self.register_topic(topic);
137 self.topic_msg_recv_counts.get_or_create(topic).inc();
138 self.topic_msg_recv_bytes
139 .get_or_create(topic)
140 .inc_by(bytes as u64);
141 }
142}