subspace_service/
metrics.rs1use futures::StreamExt;
4use parity_scale_codec::Encode;
5use sc_client_api::{BlockBackend, BlockImportNotification, ImportNotifications};
6use sp_runtime::traits::Block as BlockT;
7use std::sync::Arc;
8use substrate_prometheus_endpoint::{register, Counter, PrometheusError, Registry, U64};
9
10pub struct NodeMetrics<Block: BlockT, Client> {
11 client: Arc<Client>,
12 block_import: ImportNotifications<Block>,
13 blocks: Counter<U64>,
14 extrinsics: Counter<U64>,
15 extrinsics_size: Counter<U64>,
16 _p: std::marker::PhantomData<Block>,
17}
18
19impl<Block, Client> NodeMetrics<Block, Client>
20where
21 Block: BlockT,
22 Client: BlockBackend<Block> + 'static,
23{
24 pub fn new(
25 client: Arc<Client>,
26 block_import: ImportNotifications<Block>,
27 registry: &Registry,
28 ) -> Result<Self, PrometheusError> {
29 Ok(Self {
30 client,
31 block_import,
32 blocks: register(
33 Counter::new("subspace_node_blocks", "Total number of imported blocks")?,
34 registry,
35 )?,
36 extrinsics: register(
37 Counter::new(
38 "subspace_node_extrinsics",
39 "Total number of extrinsics in the imported blocks",
40 )?,
41 registry,
42 )?,
43 extrinsics_size: register(
44 Counter::new(
45 "subspace_node_extrinsics_size",
46 "Total extrinsic bytes in the imported blocks",
47 )?,
48 registry,
49 )?,
50 _p: Default::default(),
51 })
52 }
53
54 pub async fn run(mut self) {
55 while let Some(incoming_block) = self.block_import.next().await {
56 self.update_block_metrics(incoming_block);
57 }
58 }
59
60 fn update_block_metrics(&self, incoming_block: BlockImportNotification<Block>) {
61 let extrinsics = self
62 .client
63 .block_body(incoming_block.hash)
64 .ok()
65 .flatten()
66 .unwrap_or_default();
67 self.blocks.inc();
68 self.extrinsics.inc_by(extrinsics.len() as u64);
69 let total_size: usize = extrinsics
70 .iter()
71 .map(|extrinsic| extrinsic.encoded_size())
72 .sum();
73 self.extrinsics_size.inc_by(total_size as u64);
74 }
75}