referrerpolicy=no-referrer-when-downgrade

polkadot_network_bridge/
metrics.rs

1// Copyright (C) Parity Technologies (UK) Ltd.
2// This file is part of Polkadot.
3
4// Polkadot is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8
9// Polkadot is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License
15// along with Polkadot.  If not, see <http://www.gnu.org/licenses/>.
16
17use super::{PeerSet, ProtocolVersion};
18use polkadot_node_metrics::metrics::{self, prometheus};
19
20/// Metrics for the network bridge.
21#[derive(Clone, Default)]
22pub struct Metrics(pub(crate) Option<MetricsInner>);
23
24fn peer_set_label(peer_set: PeerSet, version: ProtocolVersion) -> &'static str {
25	// Higher level code is meant to protect against this ever happening.
26	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	// The reason why a `Histogram` is used to track a queue size is that
147	// we need not only an average size of the queue (that will be 0 normally), but
148	// we also need a dynamics for this queue size in case of messages delays.
149	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}