polkadot_node_core_provisioner/
metrics.rs1use crate::disputes::prioritized_selection::PartitionedDisputes;
18use polkadot_node_subsystem_util::metrics::{self, prometheus};
19
20#[derive(Clone)]
21struct MetricsInner {
22 inherent_data_requests: prometheus::CounterVec<prometheus::U64>,
24 request_inherent_data_duration: prometheus::Histogram,
26 provisionable_data_duration: prometheus::Histogram,
28 inherent_data_response_bitfields: prometheus::Histogram,
30
31 inherent_data_dispute_statement_sets: prometheus::Counter<prometheus::U64>,
36 inherent_data_dispute_statements: prometheus::CounterVec<prometheus::U64>,
37
38 partitioned_disputes: prometheus::CounterVec<prometheus::U64>,
40
41 fetched_onchain_disputes: prometheus::Counter<prometheus::U64>,
43
44 backable_vs_in_block: prometheus::Histogram,
47}
48
49#[derive(Default, Clone)]
51pub struct Metrics(Option<MetricsInner>);
52
53impl Metrics {
54 #[cfg(test)]
56 pub fn new_dummy() -> Metrics {
57 Metrics(None)
58 }
59
60 pub(crate) fn on_inherent_data_request(&self, response: Result<(), ()>) {
61 if let Some(metrics) = &self.0 {
62 match response {
63 Ok(()) => metrics.inherent_data_requests.with_label_values(&["succeeded"]).inc(),
64 Err(()) => metrics.inherent_data_requests.with_label_values(&["failed"]).inc(),
65 }
66 }
67 }
68
69 pub(crate) fn time_request_inherent_data(
71 &self,
72 ) -> Option<metrics::prometheus::prometheus::HistogramTimer> {
73 self.0
74 .as_ref()
75 .map(|metrics| metrics.request_inherent_data_duration.start_timer())
76 }
77
78 pub(crate) fn time_provisionable_data(
80 &self,
81 ) -> Option<metrics::prometheus::prometheus::HistogramTimer> {
82 self.0.as_ref().map(|metrics| metrics.provisionable_data_duration.start_timer())
83 }
84
85 pub(crate) fn observe_inherent_data_bitfields_count(&self, bitfields_count: usize) {
86 self.0.as_ref().map(|metrics| {
87 metrics.inherent_data_response_bitfields.observe(bitfields_count as f64)
88 });
89 }
90
91 pub(crate) fn inc_valid_statements_by(&self, votes: usize) {
92 if let Some(metrics) = &self.0 {
93 metrics
94 .inherent_data_dispute_statements
95 .with_label_values(&["valid"])
96 .inc_by(votes.try_into().unwrap_or(0));
97 }
98 }
99
100 pub(crate) fn inc_invalid_statements_by(&self, votes: usize) {
101 if let Some(metrics) = &self.0 {
102 metrics
103 .inherent_data_dispute_statements
104 .with_label_values(&["invalid"])
105 .inc_by(votes.try_into().unwrap_or(0));
106 }
107 }
108
109 pub(crate) fn inc_dispute_statement_sets_by(&self, disputes: usize) {
110 if let Some(metrics) = &self.0 {
111 metrics
112 .inherent_data_dispute_statement_sets
113 .inc_by(disputes.try_into().unwrap_or(0));
114 }
115 }
116
117 pub(crate) fn on_partition_recent_disputes(&self, disputes: &PartitionedDisputes) {
118 if let Some(metrics) = &self.0 {
119 let PartitionedDisputes {
120 inactive_unknown_onchain,
121 inactive_unconcluded_onchain: inactive_unconcluded_known_onchain,
122 active_unknown_onchain,
123 active_unconcluded_onchain,
124 active_concluded_onchain,
125 inactive_concluded_onchain: inactive_concluded_known_onchain,
126 } = disputes;
127
128 metrics
129 .partitioned_disputes
130 .with_label_values(&["inactive_unknown_onchain"])
131 .inc_by(inactive_unknown_onchain.len().try_into().unwrap_or(0));
132 metrics
133 .partitioned_disputes
134 .with_label_values(&["inactive_unconcluded_known_onchain"])
135 .inc_by(inactive_unconcluded_known_onchain.len().try_into().unwrap_or(0));
136 metrics
137 .partitioned_disputes
138 .with_label_values(&["active_unknown_onchain"])
139 .inc_by(active_unknown_onchain.len().try_into().unwrap_or(0));
140 metrics
141 .partitioned_disputes
142 .with_label_values(&["active_unconcluded_onchain"])
143 .inc_by(active_unconcluded_onchain.len().try_into().unwrap_or(0));
144 metrics
145 .partitioned_disputes
146 .with_label_values(&["active_concluded_onchain"])
147 .inc_by(active_concluded_onchain.len().try_into().unwrap_or(0));
148 metrics
149 .partitioned_disputes
150 .with_label_values(&["inactive_concluded_known_onchain"])
151 .inc_by(inactive_concluded_known_onchain.len().try_into().unwrap_or(0));
152 }
153 }
154
155 pub(crate) fn on_fetched_onchain_disputes(&self, onchain_count: u64) {
156 if let Some(metrics) = &self.0 {
157 metrics.fetched_onchain_disputes.inc_by(onchain_count);
158 }
159 }
160
161 pub(crate) fn observe_backable_vs_in_block(&self, diff: isize) {
162 self.0.as_ref().map(|metrics| metrics.backable_vs_in_block.observe(diff as f64));
163 }
164}
165
166impl metrics::Metrics for Metrics {
167 fn try_register(registry: &prometheus::Registry) -> Result<Self, prometheus::PrometheusError> {
168 let metrics = MetricsInner {
169 inherent_data_requests: prometheus::register(
170 prometheus::CounterVec::new(
171 prometheus::Opts::new(
172 "polkadot_parachain_inherent_data_requests_total",
173 "Number of InherentData requests served by provisioner.",
174 ),
175 &["success"],
176 )?,
177 registry,
178 )?,
179 request_inherent_data_duration: prometheus::register(
180 prometheus::Histogram::with_opts(prometheus::HistogramOpts::new(
181 "polkadot_parachain_provisioner_request_inherent_data_time",
182 "Time spent within `provisioner::request_inherent_data`",
183 ))?,
184 registry,
185 )?,
186 provisionable_data_duration: prometheus::register(
187 prometheus::Histogram::with_opts(prometheus::HistogramOpts::new(
188 "polkadot_parachain_provisioner_provisionable_data_time",
189 "Time spent within `provisioner::provisionable_data`",
190 ))?,
191 registry,
192 )?,
193 inherent_data_dispute_statements: prometheus::register(
194 prometheus::CounterVec::new(
195 prometheus::Opts::new(
196 "polkadot_parachain_inherent_data_dispute_statements",
197 "Number of dispute statements passed to `create_inherent()`.",
198 ),
199 &["validity"],
200 )?,
201 ®istry,
202 )?,
203 inherent_data_dispute_statement_sets: prometheus::register(
204 prometheus::Counter::new(
205 "polkadot_parachain_inherent_data_dispute_statement_sets",
206 "Number of dispute statements sets passed to `create_inherent()`.",
207 )?,
208 registry,
209 )?,
210 inherent_data_response_bitfields: prometheus::register(
211 prometheus::Histogram::with_opts(
212 prometheus::HistogramOpts::new(
213 "polkadot_parachain_provisioner_inherent_data_response_bitfields_sent",
214 "Number of inherent bitfields sent in response to `ProvisionerMessage::RequestInherentData`.",
215 ).buckets(vec![0.0, 25.0, 50.0, 100.0, 150.0, 200.0, 250.0, 300.0, 400.0, 500.0, 600.0]),
216 )?,
217 registry,
218 )?,
219 backable_vs_in_block: prometheus::register(
220 prometheus::Histogram::with_opts(
221 prometheus::HistogramOpts::new(
222 "polkadot_parachain_provisioner_backable_vs_in_block",
223 "Difference between number of backable blocks and number of backed candidates in block",
224 ).buckets(vec![-100.0, -50.0, -40.0, -30.0, -20.0, -15.0, -10.0, -5.0, 0.0, 5.0, 10.0, 15.0, 20.0, 30.0, 40.0, 50.0, 100.0]),
225 )?,
226 registry,
227 )?,
228 partitioned_disputes: prometheus::register(
229 prometheus::CounterVec::new(
230 prometheus::Opts::new(
231 "polkadot_parachain_provisioner_partitioned_disputes",
232 "Number of disputes partitioned by type.",
233 ),
234 &["partition"],
235 )?,
236 ®istry,
237 )?,
238 fetched_onchain_disputes: prometheus::register(
239 prometheus::Counter::new("polkadot_parachain_fetched_onchain_disputes", "Number of disputes fetched from the runtime"
240 )?,
241 ®istry,
242 )?,
243 };
244 Ok(Metrics(Some(metrics)))
245 }
246}