referrerpolicy=no-referrer-when-downgrade

polkadot_node_core_dispute_coordinator/
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 polkadot_node_subsystem_util::metrics::{self, prometheus};
18
19#[derive(Clone)]
20struct MetricsInner {
21	/// Number of opened disputes.
22	open: prometheus::Counter<prometheus::U64>,
23	/// Votes of all disputes.
24	votes: prometheus::CounterVec<prometheus::U64>,
25	/// Number of approval votes explicitly fetched from approval voting.
26	approval_votes: prometheus::Counter<prometheus::U64>,
27	/// Conclusion across all disputes.
28	concluded: prometheus::CounterVec<prometheus::U64>,
29	/// Number of participations that have been queued.
30	queued_participations: prometheus::CounterVec<prometheus::U64>,
31	/// How long vote cleanup batches take.
32	vote_cleanup_time: prometheus::Histogram,
33	/// Number of refrained participations.
34	refrained_participations: prometheus::Counter<prometheus::U64>,
35	/// Number of unactivated disputes.
36	unactivated: prometheus::Counter<prometheus::U64>,
37	/// Distribution of participation durations.
38	participation_durations: prometheus::Histogram,
39	/// Measures the duration of the full participation pipeline: From when
40	/// a participation request is first queued to when participation in the
41	/// requested dispute is complete.
42	participation_pipeline_durations: prometheus::Histogram,
43	/// Size of participation priority queue
44	participation_priority_queue_size: prometheus::Gauge<prometheus::U64>,
45	/// Size of participation best effort queue
46	participation_best_effort_queue_size: prometheus::Gauge<prometheus::U64>,
47}
48
49/// Candidate validation metrics.
50#[derive(Default, Clone)]
51pub struct Metrics(Option<MetricsInner>);
52
53impl Metrics {
54	pub(crate) fn on_open(&self) {
55		if let Some(metrics) = &self.0 {
56			metrics.open.inc();
57		}
58	}
59
60	pub(crate) fn on_valid_votes(&self, vote_count: u32) {
61		if let Some(metrics) = &self.0 {
62			metrics.votes.with_label_values(&["valid"]).inc_by(vote_count as _);
63		}
64	}
65
66	pub(crate) fn on_invalid_votes(&self, vote_count: u32) {
67		if let Some(metrics) = &self.0 {
68			metrics.votes.with_label_values(&["invalid"]).inc_by(vote_count as _);
69		}
70	}
71
72	pub(crate) fn on_approval_votes(&self, vote_count: u32) {
73		if let Some(metrics) = &self.0 {
74			metrics.approval_votes.inc_by(vote_count as _);
75		}
76	}
77
78	pub(crate) fn on_concluded_valid(&self) {
79		if let Some(metrics) = &self.0 {
80			metrics.concluded.with_label_values(&["valid"]).inc();
81		}
82	}
83
84	pub(crate) fn on_concluded_invalid(&self) {
85		if let Some(metrics) = &self.0 {
86			metrics.concluded.with_label_values(&["invalid"]).inc();
87		}
88	}
89
90	pub(crate) fn on_queued_priority_participation(&self) {
91		if let Some(metrics) = &self.0 {
92			metrics.queued_participations.with_label_values(&["priority"]).inc();
93		}
94	}
95
96	pub(crate) fn on_queued_best_effort_participation(&self) {
97		if let Some(metrics) = &self.0 {
98			metrics.queued_participations.with_label_values(&["best-effort"]).inc();
99		}
100	}
101
102	pub(crate) fn time_vote_cleanup(&self) -> Option<prometheus::prometheus::HistogramTimer> {
103		self.0.as_ref().map(|metrics| metrics.vote_cleanup_time.start_timer())
104	}
105
106	pub(crate) fn on_refrained_participation(&self) {
107		if let Some(metrics) = &self.0 {
108			metrics.refrained_participations.inc();
109		}
110	}
111
112	/// Provide a timer for participation durations which updates on drop.
113	pub(crate) fn time_participation(
114		&self,
115	) -> Option<metrics::prometheus::prometheus::HistogramTimer> {
116		self.0.as_ref().map(|metrics| metrics.participation_durations.start_timer())
117	}
118
119	/// Provide a timer for participation pipeline durations which updates on drop.
120	pub(crate) fn time_participation_pipeline(
121		&self,
122	) -> Option<metrics::prometheus::prometheus::HistogramTimer> {
123		self.0
124			.as_ref()
125			.map(|metrics| metrics.participation_pipeline_durations.start_timer())
126	}
127
128	/// Set the `priority_queue_size` metric
129	pub fn report_priority_queue_size(&self, size: u64) {
130		if let Some(metrics) = &self.0 {
131			metrics.participation_priority_queue_size.set(size);
132		}
133	}
134
135	/// Set the `best_effort_queue_size` metric
136	pub fn report_best_effort_queue_size(&self, size: u64) {
137		if let Some(metrics) = &self.0 {
138			metrics.participation_best_effort_queue_size.set(size);
139		}
140	}
141
142	pub(crate) fn on_unactivated_dispute(&self) {
143		if let Some(metrics) = &self.0 {
144			metrics.unactivated.inc();
145		}
146	}
147}
148
149impl metrics::Metrics for Metrics {
150	fn try_register(registry: &prometheus::Registry) -> Result<Self, prometheus::PrometheusError> {
151		let metrics = MetricsInner {
152			open: prometheus::register(
153				prometheus::Counter::with_opts(prometheus::Opts::new(
154					"polkadot_parachain_candidate_disputes_total",
155					"Total number of raised disputes.",
156				))?,
157				registry,
158			)?,
159			concluded: prometheus::register(
160				prometheus::CounterVec::new(
161					prometheus::Opts::new(
162						"polkadot_parachain_candidate_dispute_concluded",
163						"Concluded dispute votes, sorted by candidate is `valid` and `invalid`.",
164					),
165					&["validity"],
166				)?,
167				registry,
168			)?,
169			votes: prometheus::register(
170				prometheus::CounterVec::new(
171					prometheus::Opts::new(
172						"polkadot_parachain_candidate_dispute_votes",
173						"Accumulated dispute votes, sorted by candidate is `valid` and `invalid`.",
174					),
175					&["validity"],
176				)?,
177				registry,
178			)?,
179			approval_votes: prometheus::register(
180				prometheus::Counter::with_opts(prometheus::Opts::new(
181					"polkadot_parachain_dispute_candidate_approval_votes_fetched_total",
182					"Number of approval votes fetched from approval voting.",
183				))?,
184				registry,
185			)?,
186			queued_participations: prometheus::register(
187				prometheus::CounterVec::new(
188					prometheus::Opts::new(
189						"polkadot_parachain_dispute_participations",
190						"Total number of queued participations, grouped by priority and best-effort. (Not every queueing will necessarily lead to an actual participation because of duplicates.)",
191					),
192					&["priority"],
193				)?,
194				registry,
195			)?,
196			vote_cleanup_time: prometheus::register(
197				prometheus::Histogram::with_opts(
198					prometheus::HistogramOpts::new(
199						"polkadot_parachain_dispute_coordinator_vote_cleanup",
200						"Time spent cleaning up old votes per batch.",
201					)
202					.buckets([0.01, 0.1, 0.5, 1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0].into()),
203				)?,
204				registry,
205			)?,
206			refrained_participations: prometheus::register(
207			prometheus::Counter::with_opts(
208				prometheus::Opts::new(
209					"polkadot_parachain_dispute_refrained_participations",
210					"Number of refrained participations. We refrain from participation if all of the following conditions are met: disputed candidate is not included, not backed and not confirmed.",
211				))?,
212				registry,
213			)?,
214			participation_durations: prometheus::register(
215				prometheus::Histogram::with_opts(
216					prometheus::HistogramOpts::new(
217						"polkadot_parachain_dispute_participation_durations",
218						"Time spent within fn Participation::participate",
219					)
220				)?,
221				registry,
222			)?,
223			participation_pipeline_durations: prometheus::register(
224				prometheus::Histogram::with_opts(
225					prometheus::HistogramOpts::new(
226						"polkadot_parachain_dispute_participation_pipeline_durations",
227						"Measures the duration of the full participation pipeline: From when a participation request is first queued to when participation in the requested dispute is complete.",
228					)
229				)?,
230				registry,
231			)?,
232			participation_priority_queue_size: prometheus::register(
233				prometheus::Gauge::new("polkadot_parachain_dispute_participation_priority_queue_size",
234				"Number of disputes waiting for local participation in the priority queue.")?,
235				registry,
236			)?,
237			participation_best_effort_queue_size: prometheus::register(
238				prometheus::Gauge::new("polkadot_parachain_dispute_participation_best_effort_queue_size",
239				"Number of disputes waiting for local participation in the best effort queue.")?,
240				registry,
241			)?,
242			unactivated: prometheus::register(
243				prometheus::Counter::with_opts(prometheus::Opts::new(
244					"polkadot_parachain_dispute_unactivated_total",
245					"Total number of disputes that were unactivated due to all raising parties being disabled.",
246				))?,
247				registry,
248			)?,
249		};
250		Ok(Metrics(Some(metrics)))
251	}
252}