diff --git a/CHANGELOG.md b/CHANGELOG.md index 94ed231ae095..088f9b1a2479 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -50,6 +50,9 @@ snapshots instead of moving or copying them. This can be invoked with `--import-snapshot --import-mode=symlink`. +- [#4533](https://github.com/ChainSafe/forest/pull/4641) Added `build_info` + metric to Prometheus metrics, which include the current build's version. + - [#4628](https://github.com/ChainSafe/forest/issues/4628) Added support for devnets (2k networks) in the offline Forest. diff --git a/src/metrics/mod.rs b/src/metrics/mod.rs index f2d1239c2ad7..6b355a5518b4 100644 --- a/src/metrics/mod.rs +++ b/src/metrics/mod.rs @@ -80,7 +80,9 @@ where warn!("Failed to register process metrics: {err}"); } - // Add the DBCollector to the registry + DEFAULT_REGISTRY.write().register_collector(Box::new( + crate::utils::version::ForestVersionCollector::new(), + )); DEFAULT_REGISTRY .write() .register_collector(Box::new(crate::metrics::db::DBCollector::new(db_directory))); diff --git a/src/utils/version/mod.rs b/src/utils/version/mod.rs index 792525298f32..779a73e20fae 100644 --- a/src/utils/version/mod.rs +++ b/src/utils/version/mod.rs @@ -3,6 +3,11 @@ use git_version::git_version; use once_cell::sync::Lazy; +use prometheus_client::{ + collector::Collector, + encoding::{DescriptorEncoder, EncodeLabelSet, EncodeMetric}, + metrics::{family::Family, gauge::Gauge}, +}; /// Current git commit hash of the Forest repository. pub const GIT_HASH: &str = @@ -15,3 +20,43 @@ pub static FOREST_VERSION_STRING: Lazy = pub static FOREST_VERSION: Lazy = Lazy::new(|| semver::Version::parse(env!("CARGO_PKG_VERSION")).expect("Invalid version")); + +#[derive(Clone, Debug, Hash, PartialEq, Eq, EncodeLabelSet)] +pub struct VersionLabel { + version: &'static str, +} + +impl VersionLabel { + pub const fn new(version: &'static str) -> Self { + Self { version } + } +} + +#[derive(Debug)] +pub struct ForestVersionCollector { + version: Family, +} + +impl ForestVersionCollector { + pub fn new() -> Self { + Self { + version: Family::default(), + } + } +} + +impl Collector for ForestVersionCollector { + fn encode(&self, mut encoder: DescriptorEncoder) -> Result<(), std::fmt::Error> { + let metric_encoder = encoder.encode_descriptor( + "build_info", + "semantic version of the forest binary", + None, + self.version.metric_type(), + )?; + self.version + .get_or_create(&VersionLabel::new(FOREST_VERSION_STRING.as_str())) + .set(1); + self.version.encode(metric_encoder)?; + Ok(()) + } +}