1use super::{PeerSet, ProtocolVersion};
18use polkadot_node_metrics::metrics::{self, prometheus};
19
20#[derive(Clone, Default)]
22pub struct Metrics(pub(crate) Option<MetricsInner>);
23
24fn peer_set_label(peer_set: PeerSet, version: ProtocolVersion) -> &'static str {
25 peer_set.get_protocol_label(version).unwrap_or("<internal error>")
27}
28
29#[allow(missing_docs)]
30impl Metrics {
31 pub fn on_peer_connected(&self, peer_set: PeerSet, version: ProtocolVersion) {
32 self.0.as_ref().map(|metrics| {
33 metrics
34 .connected_events
35 .with_label_values(&[peer_set_label(peer_set, version)])
36 .inc()
37 });
38 }
39
40 pub fn on_peer_disconnected(&self, peer_set: PeerSet, version: ProtocolVersion) {
41 self.0.as_ref().map(|metrics| {
42 metrics
43 .disconnected_events
44 .with_label_values(&[peer_set_label(peer_set, version)])
45 .inc()
46 });
47 }
48
49 pub fn note_peer_count(&self, peer_set: PeerSet, version: ProtocolVersion, count: usize) {
50 if let Some(metrics) = self.0.as_ref() {
51 let label = peer_set_label(peer_set, version);
52 metrics.peer_count.with_label_values(&[label]).set(count as u64);
53 metrics.peer_connectivity.with_label_values(&[label]).observe(count as f64);
54 }
55 }
56
57 pub fn on_notification_received(
58 &self,
59 peer_set: PeerSet,
60 version: ProtocolVersion,
61 size: usize,
62 ) {
63 if let Some(metrics) = self.0.as_ref() {
64 metrics
65 .notifications_received
66 .with_label_values(&[peer_set_label(peer_set, version)])
67 .inc();
68
69 metrics
70 .bytes_received
71 .with_label_values(&[peer_set_label(peer_set, version)])
72 .inc_by(size as u64);
73 }
74 }
75
76 pub fn on_notification_sent(
77 &self,
78 peer_set: PeerSet,
79 version: ProtocolVersion,
80 size: usize,
81 to_peers: usize,
82 ) {
83 if let Some(metrics) = self.0.as_ref() {
84 metrics
85 .notifications_sent
86 .with_label_values(&[peer_set_label(peer_set, version)])
87 .inc_by(to_peers as u64);
88
89 metrics
90 .bytes_sent
91 .with_label_values(&[peer_set_label(peer_set, version)])
92 .inc_by((size * to_peers) as u64);
93 }
94 }
95
96 pub fn note_desired_peer_count(&self, peer_set: PeerSet, size: usize) {
97 self.0.as_ref().map(|metrics| {
98 metrics
99 .desired_peer_count
100 .with_label_values(&[peer_set.get_label()])
101 .set(size as u64)
102 });
103 }
104
105 pub fn on_report_event(&self) {
106 if let Some(metrics) = self.0.as_ref() {
107 self.on_message("report_peer");
108 metrics.report_events.inc()
109 }
110 }
111
112 pub fn on_message(&self, message_type: &'static str) {
113 if let Some(metrics) = self.0.as_ref() {
114 metrics.messages_sent.with_label_values(&[message_type]).inc()
115 }
116 }
117
118 pub fn on_delayed_rx_queue(&self, queue_size: usize) {
119 if let Some(metrics) = self.0.as_ref() {
120 metrics.rx_delayed_processing.observe(queue_size as f64);
121 }
122 }
123 pub fn time_delayed_rx_events(
124 &self,
125 ) -> Option<metrics::prometheus::prometheus::HistogramTimer> {
126 self.0.as_ref().map(|metrics| metrics.rx_delayed_processing_time.start_timer())
127 }
128}
129
130#[derive(Clone)]
131pub(crate) struct MetricsInner {
132 peer_count: prometheus::GaugeVec<prometheus::U64>,
133 peer_connectivity: prometheus::HistogramVec,
134 connected_events: prometheus::CounterVec<prometheus::U64>,
135 disconnected_events: prometheus::CounterVec<prometheus::U64>,
136 desired_peer_count: prometheus::GaugeVec<prometheus::U64>,
137 report_events: prometheus::Counter<prometheus::U64>,
138
139 notifications_received: prometheus::CounterVec<prometheus::U64>,
140 notifications_sent: prometheus::CounterVec<prometheus::U64>,
141
142 bytes_received: prometheus::CounterVec<prometheus::U64>,
143 bytes_sent: prometheus::CounterVec<prometheus::U64>,
144
145 messages_sent: prometheus::CounterVec<prometheus::U64>,
146 rx_delayed_processing: prometheus::Histogram,
150 rx_delayed_processing_time: prometheus::Histogram,
151}
152
153impl metrics::Metrics for Metrics {
154 fn try_register(
155 registry: &prometheus::Registry,
156 ) -> std::result::Result<Self, prometheus::PrometheusError> {
157 let metrics = MetricsInner {
158 peer_count: prometheus::register(
159 prometheus::GaugeVec::new(
160 prometheus::Opts::new(
161 "polkadot_parachain_peer_count",
162 "The number of peers on a parachain-related peer-set",
163 ),
164 &["protocol"]
165 )?,
166 registry,
167 )?,
168 peer_connectivity: prometheus::register(
169 prometheus::HistogramVec::new(
170 prometheus::HistogramOpts::new(
171 "polkadot_parachain_peer_connectivity",
172 "Histogram of peer counts on a parachain-related peer-set to track connectivity patterns",
173 ).buckets(vec![0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 10.0, 15.0, 20.0, 25.0, 30.0, 40.0, 50.0, 100.0, 250.0, 500.0, 1000.0]),
174 &["protocol"]
175 )?,
176 registry,
177 )?,
178 connected_events: prometheus::register(
179 prometheus::CounterVec::new(
180 prometheus::Opts::new(
181 "polkadot_parachain_peer_connect_events_total",
182 "The number of peer connect events on a parachain notifications protocol",
183 ),
184 &["protocol"]
185 )?,
186 registry,
187 )?,
188 disconnected_events: prometheus::register(
189 prometheus::CounterVec::new(
190 prometheus::Opts::new(
191 "polkadot_parachain_peer_disconnect_events_total",
192 "The number of peer disconnect events on a parachain notifications protocol",
193 ),
194 &["protocol"]
195 )?,
196 registry,
197 )?,
198 desired_peer_count: prometheus::register(
199 prometheus::GaugeVec::new(
200 prometheus::Opts::new(
201 "polkadot_parachain_desired_peer_count",
202 "The number of peers that the local node is expected to connect to on a parachain-related peer-set (either including or not including unresolvable authorities, depending on whether `ConnectToValidators` or `ConnectToValidatorsResolved` was used.)",
203 ),
204 &["protocol"]
205 )?,
206 registry,
207 )?,
208 report_events: prometheus::register(
209 prometheus::Counter::new(
210 "polkadot_parachain_network_report_events_total",
211 "The amount of reputation changes issued by subsystems",
212 )?,
213 registry,
214 )?,
215 notifications_received: prometheus::register(
216 prometheus::CounterVec::new(
217 prometheus::Opts::new(
218 "polkadot_parachain_notifications_received_total",
219 "The number of notifications received on a parachain protocol",
220 ),
221 &["protocol"]
222 )?,
223 registry,
224 )?,
225 notifications_sent: prometheus::register(
226 prometheus::CounterVec::new(
227 prometheus::Opts::new(
228 "polkadot_parachain_notifications_sent_total",
229 "The number of notifications sent on a parachain protocol",
230 ),
231 &["protocol"]
232 )?,
233 registry,
234 )?,
235 bytes_received: prometheus::register(
236 prometheus::CounterVec::new(
237 prometheus::Opts::new(
238 "polkadot_parachain_notification_bytes_received_total",
239 "The number of bytes received on a parachain notification protocol",
240 ),
241 &["protocol"]
242 )?,
243 registry,
244 )?,
245 bytes_sent: prometheus::register(
246 prometheus::CounterVec::new(
247 prometheus::Opts::new(
248 "polkadot_parachain_notification_bytes_sent_total",
249 "The number of bytes sent on a parachain notification protocol",
250 ),
251 &["protocol"]
252 )?,
253 registry,
254 )?,
255 messages_sent: prometheus::register(
256 prometheus::CounterVec::new(
257 prometheus::Opts::new(
258 "polkadot_parachain_messages_sent_total",
259 "The number of messages sent via network bridge",
260 ),
261 &["type"]
262 )?,
263 registry,
264 )?,
265 rx_delayed_processing: prometheus::register(
266 prometheus::Histogram::with_opts(
267 prometheus::HistogramOpts::new(
268 "polkadot_parachain_network_bridge_rx_delayed",
269 "Number of events being delayed while broadcasting from the network bridge",
270 ).buckets(vec![0.0, 1.0, 2.0, 8.0, 16.0]),
271 )?,
272 registry,
273 )?,
274 rx_delayed_processing_time: prometheus::register(
275 prometheus::Histogram::with_opts(
276 prometheus::HistogramOpts::new(
277 "polkadot_parachain_network_bridge_rx_delayed_time",
278 "Time spent for waiting of the delayed events",
279 ),
280 )?,
281 registry,
282 )?,
283 };
284
285 Ok(Metrics(Some(metrics)))
286 }
287}