Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions crates/subspace-service/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,15 @@
#![feature(type_alias_impl_trait, type_changing_struct_update)]

pub mod dsn;
mod metrics;
pub mod piece_cache;
pub mod rpc;
pub mod segment_headers;
pub mod tx_pre_validator;

use crate::dsn::import_blocks::import_blocks as import_blocks_from_dsn;
use crate::dsn::{create_dsn_instance, DsnConfigurationError};
use crate::metrics::NodeMetrics;
use crate::piece_cache::PieceCache;
use crate::segment_headers::{start_segment_header_archiver, SegmentHeaderCache};
use crate::tx_pre_validator::PrimaryChainTxPreValidator;
Expand Down Expand Up @@ -786,6 +788,27 @@ where
}),
);

if let Some(registry) = config.prometheus_registry().as_ref() {
match NodeMetrics::new(
client.clone(),
client.import_notification_stream(),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rahulksnv this was actually slightly incorrect and fixed in dfda03c

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sg thanks

registry,
) {
Ok(node_metrics) => {
task_manager.spawn_handle().spawn(
"node_metrics",
None,
Box::pin(async move {
node_metrics.run().await;
}),
);
}
Err(err) => {
error!("Failed to initialize node metrics: {err:?}");
}
}
}

if config.offchain_worker.enabled {
sc_service::build_offchain_workers(
&config,
Expand Down
75 changes: 75 additions & 0 deletions crates/subspace-service/src/metrics.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
//! Node metrics

use futures::StreamExt;
use parity_scale_codec::Encode;
use sc_client_api::{BlockBackend, BlockImportNotification, ImportNotifications};
use sp_runtime::traits::Block as BlockT;
use std::sync::Arc;
use substrate_prometheus_endpoint::{register, Counter, PrometheusError, Registry, U64};

pub struct NodeMetrics<Block: BlockT, Client> {
client: Arc<Client>,
block_import: ImportNotifications<Block>,
blocks: Counter<U64>,
extrinsics: Counter<U64>,
extrinsics_size: Counter<U64>,
_p: std::marker::PhantomData<Block>,
}

impl<Block, Client> NodeMetrics<Block, Client>
where
Block: BlockT,
Client: BlockBackend<Block> + 'static,
{
pub fn new(
client: Arc<Client>,
block_import: ImportNotifications<Block>,
registry: &Registry,
) -> Result<Self, PrometheusError> {
Ok(Self {
client,
block_import,
blocks: register(
Counter::new("subspace_node_blocks", "Total number of imported blocks")?,
registry,
)?,
extrinsics: register(
Counter::new(
"subspace_node_extrinsics",
"Total number of extrinsics in the imported blocks",
)?,
registry,
)?,
extrinsics_size: register(
Counter::new(
"subspace_node_extrinsics_size",
"Total extrinsic bytes in the imported blocks",
)?,
registry,
)?,
_p: Default::default(),
})
}

pub async fn run(mut self) {
while let Some(incoming_block) = self.block_import.next().await {
self.update_block_metrics(incoming_block);
}
}

fn update_block_metrics(&mut self, incoming_block: BlockImportNotification<Block>) {
let extrinsics = self
.client
.block_body(incoming_block.hash)
.ok()
.flatten()
.unwrap_or(vec![]);
self.blocks.inc();
self.extrinsics.inc_by(extrinsics.len() as u64);
let total_size: usize = extrinsics
.iter()
.map(|extrinsic| extrinsic.encoded_size())
.sum();
self.extrinsics_size.inc_by(total_size as u64);
}
}