forest/networks/
metrics.rs1use std::sync::Arc;
5
6use educe::Educe;
7use prometheus_client::{
8 collector::Collector,
9 encoding::{DescriptorEncoder, EncodeMetric},
10 metrics::gauge::Gauge,
11};
12
13use super::calculate_expected_epoch;
14use crate::{networks::ChainConfig, shim::clock::ChainEpoch};
15
16#[derive(Educe)]
17#[educe(Debug)]
18pub struct NetworkHeightCollector<F>
19where
20 F: Fn() -> ChainEpoch,
21{
22 block_delay_secs: u32,
23 genesis_timestamp: u64,
24 #[educe(Debug(ignore))]
25 get_chain_head_height: Arc<F>,
26}
27
28impl<F> NetworkHeightCollector<F>
29where
30 F: Fn() -> ChainEpoch,
31{
32 pub fn new(
33 block_delay_secs: u32,
34 genesis_timestamp: u64,
35 get_chain_head_height: Arc<F>,
36 ) -> Self {
37 Self {
38 block_delay_secs,
39 genesis_timestamp,
40 get_chain_head_height,
41 }
42 }
43}
44
45impl<F> Collector for NetworkHeightCollector<F>
46where
47 F: Fn() -> ChainEpoch + Send + Sync + 'static,
48{
49 fn encode(
50 &self,
51 mut encoder: prometheus_client::encoding::DescriptorEncoder,
52 ) -> Result<(), std::fmt::Error> {
53 {
54 let network_height: Gauge = Default::default();
55 let epoch = (self.get_chain_head_height)();
56 network_height.set(epoch);
57 let metric_encoder = encoder.encode_descriptor(
58 "head_epoch",
59 "Latest epoch synchronized to the node",
60 None,
61 network_height.metric_type(),
62 )?;
63 network_height.encode(metric_encoder)?;
64 }
65 {
66 let expected_network_height: Gauge = Default::default();
67 let expected_epoch = calculate_expected_epoch(
68 chrono::Utc::now().timestamp() as u64,
69 self.genesis_timestamp,
70 self.block_delay_secs,
71 );
72 expected_network_height.set(expected_epoch);
73 let metric_encoder = encoder.encode_descriptor(
74 "expected_network_height",
75 "The expected network height based on the current time and the genesis block time",
76 None,
77 expected_network_height.metric_type(),
78 )?;
79 expected_network_height.encode(metric_encoder)?;
80 }
81 Ok(())
82 }
83}
84
85#[derive(Educe)]
86#[educe(Debug)]
87pub struct NetworkVersionCollector<F1, F2>
88where
89 F1: Fn() -> ChainEpoch,
90 F2: Fn() -> u64,
91{
92 chain_config: Arc<ChainConfig>,
93 #[educe(Debug(ignore))]
94 get_chain_head_height: Arc<F1>,
95 #[educe(Debug(ignore))]
96 get_chain_head_actor_version: Arc<F2>,
97}
98
99impl<F1, F2> NetworkVersionCollector<F1, F2>
100where
101 F1: Fn() -> ChainEpoch,
102 F2: Fn() -> u64,
103{
104 pub fn new(
105 chain_config: Arc<ChainConfig>,
106 get_chain_head_height: Arc<F1>,
107 get_chain_head_actor_version: Arc<F2>,
108 ) -> Self {
109 Self {
110 chain_config,
111 get_chain_head_height,
112 get_chain_head_actor_version,
113 }
114 }
115}
116
117impl<F1, F2> Collector for NetworkVersionCollector<F1, F2>
118where
119 F1: Fn() -> ChainEpoch + Send + Sync + 'static,
120 F2: Fn() -> u64 + Send + Sync + 'static,
121{
122 fn encode(&self, mut encoder: DescriptorEncoder) -> Result<(), std::fmt::Error> {
123 let epoch = (self.get_chain_head_height)();
124 {
125 let network_version = self.chain_config.network_version(epoch);
126 let nv_gauge: Gauge = Default::default();
127 nv_gauge.set(u32::from(network_version) as _);
128 let metric_encoder = encoder.encode_descriptor(
129 "network_version",
130 "Network version of the current chain head",
131 None,
132 nv_gauge.metric_type(),
133 )?;
134 nv_gauge.encode(metric_encoder)?;
135 }
136 {
137 let network_version_revision = self.chain_config.network_version_revision(epoch);
138 let nv_gauge: Gauge = Default::default();
139 nv_gauge.set(network_version_revision);
140 let metric_encoder = encoder.encode_descriptor(
141 "network_version_revision",
142 "Network version revision of the current chain head",
143 None,
144 nv_gauge.metric_type(),
145 )?;
146 nv_gauge.encode(metric_encoder)?;
147 }
148 {
149 let actor_version = (self.get_chain_head_actor_version)();
150 let av_gauge: Gauge = Default::default();
151 av_gauge.set(actor_version as _);
152 let metric_encoder = encoder.encode_descriptor(
153 "actor_version",
154 "Actor version of the current chain head",
155 None,
156 av_gauge.metric_type(),
157 )?;
158 av_gauge.encode(metric_encoder)?;
159 }
160 Ok(())
161 }
162}