From 014309d825643c9f57297fb172c57226bc51f05b Mon Sep 17 00:00:00 2001 From: Hubert Bugaj Date: Wed, 15 May 2024 10:46:22 +0200 Subject: [PATCH] feat: add `expected_network_height` metric --- CHANGELOG.md | 3 +++ src/daemon/mod.rs | 28 ++++++++++++++++++---------- src/networks/metrics.rs | 37 +++++++++++++++++++++++++++++++++++++ src/networks/mod.rs | 2 ++ 4 files changed, 60 insertions(+), 10 deletions(-) create mode 100644 src/networks/metrics.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index dccc4a72e879..8cbb31a3aafd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -83,6 +83,9 @@ - [#4315](https://github.com/ChainSafe/forest/pull/4315) Add support for the `Filecoin.StateGetNetworkParams` RPC method. +- [#4326](https://github.com/ChainSafe/forest/pull/4326) Added + `expected_network_height` metric to the Prometheus metrics. + ### Changed - [#4170](https://github.com/ChainSafe/forest/pull/4170) Change the default diff --git a/src/daemon/mod.rs b/src/daemon/mod.rs index 00ce90367056..7d905a4cc363 100644 --- a/src/daemon/mod.rs +++ b/src/daemon/mod.rs @@ -196,6 +196,16 @@ pub(super) async fn start( }); } + // Read Genesis file + // * When snapshot command implemented, this genesis does not need to be + // initialized + let genesis_header = read_genesis_header( + config.client.genesis_file.as_ref(), + chain_config.genesis_bytes(&db).await?.as_deref(), + &db, + ) + .await?; + if config.client.enable_metrics_endpoint { // Start Prometheus server port let prometheus_listener = TcpListener::bind(config.client.metrics_address) @@ -212,17 +222,15 @@ pub(super) async fn start( .await .context("Failed to initiate prometheus server") }); - } - // Read Genesis file - // * When snapshot command implemented, this genesis does not need to be - // initialized - let genesis_header = read_genesis_header( - config.client.genesis_file.as_ref(), - chain_config.genesis_bytes(&db).await?.as_deref(), - &db, - ) - .await?; + let chain_config_clone = chain_config.clone(); + let genesis_timestamp = genesis_header.timestamp; + services.spawn(async move { + crate::networks::metrics::network_metrics_loop(chain_config_clone, genesis_timestamp) + .await; + Ok(()) + }); + } // Initialize ChainStore let chain_store = Arc::new(ChainStore::new( diff --git a/src/networks/metrics.rs b/src/networks/metrics.rs new file mode 100644 index 000000000000..b1ce08735f5c --- /dev/null +++ b/src/networks/metrics.rs @@ -0,0 +1,37 @@ +// Copyright 2019-2024 ChainSafe Systems +// SPDX-License-Identifier: Apache-2.0, MIT + +use std::sync::Arc; + +use once_cell::sync::Lazy; +use prometheus_client::metrics::gauge::Gauge; + +use super::ChainConfig; + +pub static EXPECTED_NETWORK_HEIGHT: Lazy = Lazy::new(|| { + let metric = Gauge::default(); + crate::metrics::default_registry().register( + "expected_network_height", + "The expected network height based on the current time and the genesis block time.", + metric.clone(), + ); + metric +}); + +/// Task to periodically update network-related metrics. +pub async fn network_metrics_loop(config: Arc, genesis_timestamp: u64) { + loop { + // For this particular metric, we theoretically could have initiated the value once and + // increased it by one every `block_delay_secs`, but this would have made the metric less + // responsive and more fragile, e.g., on system clock changes. Given that the operation is cheap, we just + // recalculate it every second. + let now_epoch = chrono::Utc::now() + .timestamp() + .saturating_add(config.block_delay_secs as i64) + .saturating_sub(genesis_timestamp as i64) + / config.block_delay_secs as i64; + + EXPECTED_NETWORK_HEIGHT.set(now_epoch); + tokio::time::sleep(tokio::time::Duration::from_secs(1)).await; + } +} diff --git a/src/networks/mod.rs b/src/networks/mod.rs index 05c56e6f711f..4b1731f1a08b 100644 --- a/src/networks/mod.rs +++ b/src/networks/mod.rs @@ -30,6 +30,8 @@ pub mod calibnet; pub mod devnet; pub mod mainnet; +pub mod metrics; + /// Newest network version for all networks pub const NEWEST_NETWORK_VERSION: NetworkVersion = NetworkVersion::V17;