referrerpolicy=no-referrer-when-downgrade

polkadot_statement_distribution/
metrics.rs

1// Copyright (C) Parity Technologies (UK) Ltd.
2// Polkadot is free software: you can redistribute it and/or modify
3// it under the terms of the GNU General Public License as published by
4// the Free Software Foundation, either version 3 of the License, or
5// (at your option) any later version.
6
7// Polkadot is distributed in the hope that it will be useful,
8// but WITHOUT ANY WARRANTY; without even the implied warranty of
9// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10// GNU General Public License for more details.
11
12// You should have received a copy of the GNU General Public License
13// along with Polkadot.  If not, see <http://www.gnu.org/licenses/>.
14
15//! Metrics for the statement distribution module
16
17use polkadot_node_subsystem_util::metrics::{self, prometheus};
18
19/// Buckets more suitable for checking the typical latency values
20const HISTOGRAM_LATENCY_BUCKETS: &[f64] = &[
21	0.000025, 0.00005, 0.000075, 0.0001, 0.0003125, 0.000625, 0.00125, 0.0025, 0.005, 0.01, 0.025,
22	0.05, 0.1,
23];
24
25#[derive(Clone)]
26struct MetricsInner {
27	// V1
28	sent_requests: prometheus::Counter<prometheus::U64>,
29	received_responses: prometheus::CounterVec<prometheus::U64>,
30	network_bridge_update: prometheus::HistogramVec,
31	statements_unexpected: prometheus::CounterVec<prometheus::U64>,
32	created_message_size: prometheus::Gauge<prometheus::U64>,
33	// V1+
34	statements_distributed: prometheus::Counter<prometheus::U64>,
35	active_leaves_update: prometheus::Histogram,
36	share: prometheus::Histogram,
37	// V2+
38	peer_rate_limit_request_drop: prometheus::Counter<prometheus::U64>,
39	max_parallel_requests_reached: prometheus::Counter<prometheus::U64>,
40}
41
42/// Statement Distribution metrics.
43#[derive(Default, Clone)]
44pub struct Metrics(Option<MetricsInner>);
45
46impl Metrics {
47	/// Update statements distributed counter
48	pub fn on_statement_distributed(&self) {
49		if let Some(metrics) = &self.0 {
50			metrics.statements_distributed.inc();
51		}
52	}
53
54	/// Update statements distributed counter by an amount
55	pub fn on_statements_distributed(&self, n: usize) {
56		if let Some(metrics) = &self.0 {
57			metrics.statements_distributed.inc_by(n as u64);
58		}
59	}
60
61	/// Update sent requests counter
62	/// This counter is updated merely for the statements sent via request/response method,
63	/// meaning that it counts large statements only
64	pub fn on_sent_request(&self) {
65		if let Some(metrics) = &self.0 {
66			metrics.sent_requests.inc();
67		}
68	}
69
70	/// Update counters for the received responses with `succeeded` or `failed` labels
71	/// These counters are updated merely for the statements received via request/response method,
72	/// meaning that they count large statements only
73	pub fn on_received_response(&self, success: bool) {
74		if let Some(metrics) = &self.0 {
75			let label = if success { "succeeded" } else { "failed" };
76			metrics.received_responses.with_label_values(&[label]).inc();
77		}
78	}
79
80	/// Provide a timer for `active_leaves_update` which observes on drop.
81	pub fn time_active_leaves_update(
82		&self,
83	) -> Option<metrics::prometheus::prometheus::HistogramTimer> {
84		self.0.as_ref().map(|metrics| metrics.active_leaves_update.start_timer())
85	}
86
87	/// Provide a timer for `share` which observes on drop.
88	pub fn time_share(&self) -> Option<metrics::prometheus::prometheus::HistogramTimer> {
89		self.0.as_ref().map(|metrics| metrics.share.start_timer())
90	}
91
92	/// Provide a timer for `network_bridge_update` which observes on drop.
93	pub fn time_network_bridge_update(
94		&self,
95		message_type: &'static str,
96	) -> Option<metrics::prometheus::prometheus::HistogramTimer> {
97		self.0.as_ref().map(|metrics| {
98			metrics.network_bridge_update.with_label_values(&[message_type]).start_timer()
99		})
100	}
101
102	/// Update the out-of-view statements counter for unexpected valid statements
103	pub fn on_unexpected_statement_valid(&self) {
104		if let Some(metrics) = &self.0 {
105			metrics.statements_unexpected.with_label_values(&["valid"]).inc();
106		}
107	}
108
109	/// Update the out-of-view statements counter for unexpected seconded statements
110	pub fn on_unexpected_statement_seconded(&self) {
111		if let Some(metrics) = &self.0 {
112			metrics.statements_unexpected.with_label_values(&["seconded"]).inc();
113		}
114	}
115
116	/// Update the out-of-view statements counter for unexpected large statements
117	pub fn on_unexpected_statement_large(&self) {
118		if let Some(metrics) = &self.0 {
119			metrics.statements_unexpected.with_label_values(&["large"]).inc();
120		}
121	}
122
123	/// Report size of a created message.
124	pub fn on_created_message(&self, size: usize) {
125		if let Some(metrics) = &self.0 {
126			metrics.created_message_size.set(size as u64);
127		}
128	}
129
130	/// Update sent dropped requests counter when request dropped because
131	/// of peer rate limit
132	pub fn on_request_dropped_peer_rate_limit(&self) {
133		if let Some(metrics) = &self.0 {
134			metrics.peer_rate_limit_request_drop.inc();
135		}
136	}
137
138	/// Update max parallel requests reached counter
139	/// This counter is updated when the maximum number of parallel requests is reached
140	/// and we are waiting for one of the requests to finish
141	pub fn on_max_parallel_requests_reached(&self) {
142		if let Some(metrics) = &self.0 {
143			metrics.max_parallel_requests_reached.inc();
144		}
145	}
146}
147
148impl metrics::Metrics for Metrics {
149	fn try_register(
150		registry: &prometheus::Registry,
151	) -> std::result::Result<Self, prometheus::PrometheusError> {
152		let metrics = MetricsInner {
153			statements_distributed: prometheus::register(
154				prometheus::Counter::new(
155					"polkadot_parachain_statements_distributed_total",
156					"Number of candidate validity statements distributed to other peers.",
157				)?,
158				registry,
159			)?,
160			sent_requests: prometheus::register(
161				prometheus::Counter::new(
162					"polkadot_parachain_statement_distribution_sent_requests_total",
163					"Number of large statement fetching requests sent.",
164				)?,
165				registry,
166			)?,
167			received_responses: prometheus::register(
168				prometheus::CounterVec::new(
169					prometheus::Opts::new(
170						"polkadot_parachain_statement_distribution_received_responses_total",
171						"Number of received responses for large statement data.",
172					),
173					&["success"],
174				)?,
175				registry,
176			)?,
177			active_leaves_update: prometheus::register(
178				prometheus::Histogram::with_opts(
179					prometheus::HistogramOpts::new(
180						"polkadot_parachain_statement_distribution_active_leaves_update",
181						"Time spent within `statement_distribution::active_leaves_update`",
182					)
183					.buckets(HISTOGRAM_LATENCY_BUCKETS.into()),
184				)?,
185				registry,
186			)?,
187			share: prometheus::register(
188				prometheus::Histogram::with_opts(
189					prometheus::HistogramOpts::new(
190						"polkadot_parachain_statement_distribution_share",
191						"Time spent within `statement_distribution::share`",
192					)
193					.buckets(HISTOGRAM_LATENCY_BUCKETS.into()),
194				)?,
195				registry,
196			)?,
197			network_bridge_update: prometheus::register(
198				prometheus::HistogramVec::new(
199					prometheus::HistogramOpts::new(
200						"polkadot_parachain_statement_distribution_network_bridge_update",
201						"Time spent within `statement_distribution::network_bridge_update`",
202					)
203					.buckets(HISTOGRAM_LATENCY_BUCKETS.into()),
204					&["message_type"],
205				)?,
206				registry,
207			)?,
208			statements_unexpected: prometheus::register(
209				prometheus::CounterVec::new(
210					prometheus::Opts::new(
211						"polkadot_parachain_statement_distribution_statements_unexpected",
212						"Number of statements that were not expected to be received.",
213					),
214					&["type"],
215				)?,
216				registry,
217			)?,
218			created_message_size: prometheus::register(
219				prometheus::Gauge::with_opts(prometheus::Opts::new(
220					"polkadot_parachain_statement_distribution_created_message_size",
221					"Size of created messages containing Seconded statements.",
222				))?,
223				registry,
224			)?,
225			peer_rate_limit_request_drop: prometheus::register(
226				prometheus::Counter::new(
227					"polkadot_parachain_statement_distribution_peer_rate_limit_request_drop_total",
228					"Number of statement distribution requests dropped because of the peer rate limiting.",
229				)?,
230				registry,
231			)?,
232			max_parallel_requests_reached: prometheus::register(
233				prometheus::Counter::new(
234					"polkadot_parachain_statement_distribution_max_parallel_requests_reached_total",
235					"Number of times the maximum number of parallel requests was reached.",
236				)?,
237				registry,
238			)?,
239		};
240		Ok(Metrics(Some(metrics)))
241	}
242}