1use super::*;
20pub use polkadot_node_metrics::metrics::{self, prometheus, Metrics as MetricsTrait};
21
22#[derive(Clone)]
24struct MetricsInner {
25 activated_heads_total: prometheus::Counter<prometheus::U64>,
26 deactivated_heads_total: prometheus::Counter<prometheus::U64>,
27 messages_relayed_total: prometheus::Counter<prometheus::U64>,
28
29 to_subsystem_bounded_tof: prometheus::HistogramVec,
30 to_subsystem_bounded_sent: prometheus::GaugeVec<prometheus::U64>,
31 to_subsystem_bounded_received: prometheus::GaugeVec<prometheus::U64>,
32 to_subsystem_bounded_blocked: prometheus::GaugeVec<prometheus::U64>,
33
34 to_subsystem_unbounded_tof: prometheus::HistogramVec,
35 to_subsystem_unbounded_sent: prometheus::GaugeVec<prometheus::U64>,
36 to_subsystem_unbounded_received: prometheus::GaugeVec<prometheus::U64>,
37
38 signals_sent: prometheus::GaugeVec<prometheus::U64>,
39 signals_received: prometheus::GaugeVec<prometheus::U64>,
40
41 #[cfg(any(target_os = "linux", feature = "jemalloc-allocator"))]
42 memory_stats_resident: prometheus::Gauge<prometheus::U64>,
43 #[cfg(any(target_os = "linux", feature = "jemalloc-allocator"))]
44 memory_stats_allocated: prometheus::Gauge<prometheus::U64>,
45}
46
47#[derive(Default, Clone)]
49pub struct Metrics(Option<MetricsInner>);
50
51impl Metrics {
52 pub(crate) fn on_head_activated(&self) {
53 if let Some(metrics) = &self.0 {
54 metrics.activated_heads_total.inc();
55 }
56 }
57
58 pub(crate) fn on_head_deactivated(&self) {
59 if let Some(metrics) = &self.0 {
60 metrics.deactivated_heads_total.inc();
61 }
62 }
63
64 pub(crate) fn on_message_relayed(&self) {
65 if let Some(metrics) = &self.0 {
66 metrics.messages_relayed_total.inc();
67 }
68 }
69
70 #[cfg(any(target_os = "linux", feature = "jemalloc-allocator"))]
71 pub(crate) fn memory_stats_snapshot(
72 &self,
73 memory_stats: memory_stats::MemoryAllocationSnapshot,
74 ) {
75 if let Some(metrics) = &self.0 {
76 metrics.memory_stats_allocated.set(memory_stats.allocated as u64);
77 metrics.memory_stats_resident.set(memory_stats.resident as u64);
78 }
79 }
80
81 pub(crate) fn channel_metrics_snapshot(
82 &self,
83 collection: impl IntoIterator<Item = (&'static str, SubsystemMeterReadouts)>,
84 ) {
85 if let Some(metrics) = &self.0 {
86 collection
87 .into_iter()
88 .for_each(|(name, readouts): (_, SubsystemMeterReadouts)| {
89 metrics
90 .to_subsystem_bounded_sent
91 .with_label_values(&[name])
92 .set(readouts.bounded.sent as u64);
93
94 metrics
95 .to_subsystem_bounded_received
96 .with_label_values(&[name])
97 .set(readouts.bounded.received as u64);
98
99 metrics
100 .to_subsystem_bounded_blocked
101 .with_label_values(&[name])
102 .set(readouts.bounded.blocked as u64);
103
104 metrics
105 .to_subsystem_unbounded_sent
106 .with_label_values(&[name])
107 .set(readouts.unbounded.sent as u64);
108
109 metrics
110 .to_subsystem_unbounded_received
111 .with_label_values(&[name])
112 .set(readouts.unbounded.received as u64);
113
114 metrics
115 .signals_sent
116 .with_label_values(&[name])
117 .set(readouts.signals.sent as u64);
118
119 metrics
120 .signals_received
121 .with_label_values(&[name])
122 .set(readouts.signals.received as u64);
123
124 let hist_bounded = metrics.to_subsystem_bounded_tof.with_label_values(&[name]);
125 for tof in readouts.bounded.tof {
126 hist_bounded.observe(tof.as_f64());
127 }
128
129 let hist_unbounded =
130 metrics.to_subsystem_unbounded_tof.with_label_values(&[name]);
131 for tof in readouts.unbounded.tof {
132 hist_unbounded.observe(tof.as_f64());
133 }
134 });
135 }
136 }
137}
138
139impl MetricsTrait for Metrics {
140 fn try_register(registry: &prometheus::Registry) -> Result<Self, prometheus::PrometheusError> {
141 let metrics = MetricsInner {
142 activated_heads_total: prometheus::register(
143 prometheus::Counter::new(
144 "polkadot_parachain_activated_heads_total",
145 "Number of activated heads.",
146 )?,
147 registry,
148 )?,
149 deactivated_heads_total: prometheus::register(
150 prometheus::Counter::new(
151 "polkadot_parachain_deactivated_heads_total",
152 "Number of deactivated heads.",
153 )?,
154 registry,
155 )?,
156 messages_relayed_total: prometheus::register(
157 prometheus::Counter::new(
158 "polkadot_parachain_messages_relayed_total",
159 "Number of messages relayed by Overseer.",
160 )?,
161 registry,
162 )?,
163 to_subsystem_bounded_tof: prometheus::register(
164 prometheus::HistogramVec::new(
165 prometheus::HistogramOpts::new(
166 "polkadot_parachain_subsystem_bounded_tof",
167 "Duration spent in a particular channel from entrance to removal",
168 )
169 .buckets(vec![
170 0.0001, 0.0004, 0.0016, 0.0064, 0.0256, 0.1024, 0.4096, 1.6384, 3.2768,
171 4.9152, 6.5536,
172 ]),
173 &["subsystem_name"],
174 )?,
175 registry,
176 )?,
177 to_subsystem_bounded_sent: prometheus::register(
178 prometheus::GaugeVec::<prometheus::U64>::new(
179 prometheus::Opts::new(
180 "polkadot_parachain_subsystem_bounded_sent",
181 "Number of elements sent to subsystems' bounded queues",
182 ),
183 &["subsystem_name"],
184 )?,
185 registry,
186 )?,
187 to_subsystem_bounded_received: prometheus::register(
188 prometheus::GaugeVec::<prometheus::U64>::new(
189 prometheus::Opts::new(
190 "polkadot_parachain_subsystem_bounded_received",
191 "Number of elements received by subsystems' bounded queues",
192 ),
193 &["subsystem_name"],
194 )?,
195 registry,
196 )?,
197 to_subsystem_bounded_blocked: prometheus::register(
198 prometheus::GaugeVec::<prometheus::U64>::new(
199 prometheus::Opts::new(
200 "polkadot_parachain_subsystem_bounded_blocked",
201 "Number of times senders blocked while sending messages to a subsystem",
202 ),
203 &["subsystem_name"],
204 )?,
205 registry,
206 )?,
207 to_subsystem_unbounded_tof: prometheus::register(
208 prometheus::HistogramVec::new(
209 prometheus::HistogramOpts::new(
210 "polkadot_parachain_subsystem_unbounded_tof",
211 "Duration spent in a particular channel from entrance to removal",
212 )
213 .buckets(vec![
214 0.0001, 0.0004, 0.0016, 0.0064, 0.0256, 0.1024, 0.4096, 1.6384, 3.2768,
215 4.9152, 6.5536,
216 ]),
217 &["subsystem_name"],
218 )?,
219 registry,
220 )?,
221 to_subsystem_unbounded_sent: prometheus::register(
222 prometheus::GaugeVec::<prometheus::U64>::new(
223 prometheus::Opts::new(
224 "polkadot_parachain_subsystem_unbounded_sent",
225 "Number of elements sent to subsystems' unbounded queues",
226 ),
227 &["subsystem_name"],
228 )?,
229 registry,
230 )?,
231 to_subsystem_unbounded_received: prometheus::register(
232 prometheus::GaugeVec::<prometheus::U64>::new(
233 prometheus::Opts::new(
234 "polkadot_parachain_subsystem_unbounded_received",
235 "Number of elements received by subsystems' unbounded queues",
236 ),
237 &["subsystem_name"],
238 )?,
239 registry,
240 )?,
241 signals_sent: prometheus::register(
242 prometheus::GaugeVec::<prometheus::U64>::new(
243 prometheus::Opts::new(
244 "polkadot_parachain_overseer_signals_sent",
245 "Number of signals sent by overseer to subsystems",
246 ),
247 &["subsystem_name"],
248 )?,
249 registry,
250 )?,
251 signals_received: prometheus::register(
252 prometheus::GaugeVec::<prometheus::U64>::new(
253 prometheus::Opts::new(
254 "polkadot_parachain_overseer_signals_received",
255 "Number of signals received by subsystems from overseer",
256 ),
257 &["subsystem_name"],
258 )?,
259 registry,
260 )?,
261 #[cfg(any(target_os = "linux", feature = "jemalloc-allocator"))]
262 memory_stats_allocated: prometheus::register(
263 prometheus::Gauge::<prometheus::U64>::new(
264 "polkadot_memory_allocated",
265 "Total bytes allocated by the node",
266 )?,
267 registry,
268 )?,
269 #[cfg(any(target_os = "linux", feature = "jemalloc-allocator"))]
270 memory_stats_resident: prometheus::register(
271 prometheus::Gauge::<prometheus::U64>::new(
272 "polkadot_memory_resident",
273 "Bytes allocated by the node, and held in RAM",
274 )?,
275 registry,
276 )?,
277 };
278 Ok(Metrics(Some(metrics)))
279 }
280}
281
282impl fmt::Debug for Metrics {
283 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
284 f.write_str("Metrics {{...}}")
285 }
286}