polkadot_node_core_dispute_coordinator/
metrics.rs1use polkadot_node_subsystem_util::metrics::{self, prometheus};
18
19#[derive(Clone)]
20struct MetricsInner {
21 open: prometheus::Counter<prometheus::U64>,
23 votes: prometheus::CounterVec<prometheus::U64>,
25 approval_votes: prometheus::Counter<prometheus::U64>,
27 concluded: prometheus::CounterVec<prometheus::U64>,
29 queued_participations: prometheus::CounterVec<prometheus::U64>,
31 vote_cleanup_time: prometheus::Histogram,
33 refrained_participations: prometheus::Counter<prometheus::U64>,
35 unactivated: prometheus::Counter<prometheus::U64>,
37 participation_durations: prometheus::Histogram,
39 participation_pipeline_durations: prometheus::Histogram,
43 participation_priority_queue_size: prometheus::Gauge<prometheus::U64>,
45 participation_best_effort_queue_size: prometheus::Gauge<prometheus::U64>,
47}
48
49#[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 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 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 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 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}