messages_relay/
metrics.rs
1use crate::{
20 message_lane::MessageLane,
21 message_lane_loop::{SourceClientState, TargetClientState},
22};
23
24use bp_messages::{HashedLaneId, LegacyLaneId, MessageNonce};
25use finality_relay::SyncLoopMetrics;
26use relay_utils::metrics::{
27 metric_name, register, GaugeVec, Metric, Opts, PrometheusError, Registry, U64,
28};
29
30#[derive(Clone)]
34pub struct MessageLaneLoopMetrics {
35 source_to_target_finality_metrics: SyncLoopMetrics,
37 target_to_source_finality_metrics: SyncLoopMetrics,
39 lane_state_nonces: GaugeVec<U64>,
42}
43
44impl MessageLaneLoopMetrics {
45 pub fn new(prefix: Option<&str>) -> Result<Self, PrometheusError> {
47 Ok(MessageLaneLoopMetrics {
48 source_to_target_finality_metrics: SyncLoopMetrics::new(
49 prefix,
50 "source",
51 "source_at_target",
52 )?,
53 target_to_source_finality_metrics: SyncLoopMetrics::new(
54 prefix,
55 "target",
56 "target_at_source",
57 )?,
58 lane_state_nonces: GaugeVec::new(
59 Opts::new(metric_name(prefix, "lane_state_nonces"), "Nonces of the lane state"),
60 &["type"],
61 )?,
62 })
63 }
64
65 pub fn update_source_state<P: MessageLane>(&self, source_client_state: SourceClientState<P>) {
67 self.source_to_target_finality_metrics
68 .update_best_block_at_source(source_client_state.best_self.0);
69 if let Some(best_finalized_peer_at_best_self) =
70 source_client_state.best_finalized_peer_at_best_self
71 {
72 self.target_to_source_finality_metrics
73 .update_best_block_at_target(best_finalized_peer_at_best_self.0);
74 if let Some(actual_best_finalized_peer_at_best_self) =
75 source_client_state.actual_best_finalized_peer_at_best_self
76 {
77 self.target_to_source_finality_metrics.update_using_same_fork(
78 best_finalized_peer_at_best_self.1 == actual_best_finalized_peer_at_best_self.1,
79 );
80 }
81 }
82 }
83
84 pub fn update_target_state<P: MessageLane>(&self, target_client_state: TargetClientState<P>) {
86 self.target_to_source_finality_metrics
87 .update_best_block_at_source(target_client_state.best_self.0);
88 if let Some(best_finalized_peer_at_best_self) =
89 target_client_state.best_finalized_peer_at_best_self
90 {
91 self.source_to_target_finality_metrics
92 .update_best_block_at_target(best_finalized_peer_at_best_self.0);
93 if let Some(actual_best_finalized_peer_at_best_self) =
94 target_client_state.actual_best_finalized_peer_at_best_self
95 {
96 self.source_to_target_finality_metrics.update_using_same_fork(
97 best_finalized_peer_at_best_self.1 == actual_best_finalized_peer_at_best_self.1,
98 );
99 }
100 }
101 }
102
103 pub fn update_source_latest_generated_nonce(
105 &self,
106 source_latest_generated_nonce: MessageNonce,
107 ) {
108 self.lane_state_nonces
109 .with_label_values(&["source_latest_generated"])
110 .set(source_latest_generated_nonce);
111 }
112
113 pub fn update_source_latest_confirmed_nonce(
115 &self,
116 source_latest_confirmed_nonce: MessageNonce,
117 ) {
118 self.lane_state_nonces
119 .with_label_values(&["source_latest_confirmed"])
120 .set(source_latest_confirmed_nonce);
121 }
122
123 pub fn update_target_latest_received_nonce(&self, target_latest_generated_nonce: MessageNonce) {
125 self.lane_state_nonces
126 .with_label_values(&["target_latest_received"])
127 .set(target_latest_generated_nonce);
128 }
129
130 pub fn update_target_latest_confirmed_nonce(
132 &self,
133 target_latest_confirmed_nonce: MessageNonce,
134 ) {
135 self.lane_state_nonces
136 .with_label_values(&["target_latest_confirmed"])
137 .set(target_latest_confirmed_nonce);
138 }
139}
140
141impl Metric for MessageLaneLoopMetrics {
142 fn register(&self, registry: &Registry) -> Result<(), PrometheusError> {
143 self.source_to_target_finality_metrics.register(registry)?;
144 self.target_to_source_finality_metrics.register(registry)?;
145 register(self.lane_state_nonces.clone(), registry)?;
146 Ok(())
147 }
148}
149
150pub trait Labeled {
152 fn label(&self) -> String;
154}
155
156impl Labeled for LegacyLaneId {
158 fn label(&self) -> String {
159 hex::encode(self.0)
160 }
161}
162
163impl Labeled for HashedLaneId {
165 fn label(&self) -> String {
166 format!("{:?}", self.inner())
167 }
168}
169
170#[test]
171fn lane_to_label_works() {
172 assert_eq!(
173 "0x0101010101010101010101010101010101010101010101010101010101010101",
174 HashedLaneId::from_inner(sp_core::H256::from([1u8; 32])).label(),
175 );
176 assert_eq!("00000001", LegacyLaneId([0, 0, 0, 1]).label());
177}