diff --git a/crates/astria-composer/src/main.rs b/crates/astria-composer/src/main.rs index 4cbff824a..0dea447e6 100644 --- a/crates/astria-composer/src/main.rs +++ b/crates/astria-composer/src/main.rs @@ -38,11 +38,10 @@ async fn main() -> ExitCode { if !cfg.no_metrics { telemetry_conf = telemetry_conf .metrics_addr(&cfg.metrics_http_listener_addr) - .service_name(env!("CARGO_PKG_NAME")); + .service_name(env!("CARGO_PKG_NAME")) + .register_metrics(metrics_init::register); } - metrics_init::register(); - if let Err(e) = telemetry_conf .try_init() .wrap_err("failed to setup telemetry") diff --git a/crates/astria-conductor/src/main.rs b/crates/astria-conductor/src/main.rs index ee4e78a6f..c96d907ef 100644 --- a/crates/astria-conductor/src/main.rs +++ b/crates/astria-conductor/src/main.rs @@ -45,7 +45,8 @@ async fn main() -> ExitCode { if !cfg.no_metrics { telemetry_conf = telemetry_conf .metrics_addr(&cfg.metrics_http_listener_addr) - .service_name(env!("CARGO_PKG_NAME")); + .service_name(env!("CARGO_PKG_NAME")) + .register_metrics(|| {}); // conductor currently has no metrics } if let Err(e) = telemetry_conf diff --git a/crates/astria-sequencer-relayer/src/main.rs b/crates/astria-sequencer-relayer/src/main.rs index fde982f4d..b5e3dab8b 100644 --- a/crates/astria-sequencer-relayer/src/main.rs +++ b/crates/astria-sequencer-relayer/src/main.rs @@ -35,9 +35,9 @@ async fn main() -> ExitCode { if !cfg.no_metrics { telemetry_conf = telemetry_conf .metrics_addr(&cfg.metrics_http_listener_addr) - .service_name(env!("CARGO_PKG_NAME")); + .service_name(env!("CARGO_PKG_NAME")) + .register_metrics(metrics_init::register); } - metrics_init::register(); if let Err(e) = telemetry_conf .try_init() diff --git a/crates/astria-sequencer/src/main.rs b/crates/astria-sequencer/src/main.rs index a233ae81a..a89f003c5 100644 --- a/crates/astria-sequencer/src/main.rs +++ b/crates/astria-sequencer/src/main.rs @@ -36,9 +36,9 @@ async fn main() -> ExitCode { if !cfg.no_metrics { telemetry_conf = telemetry_conf .metrics_addr(&cfg.metrics_http_listener_addr) - .service_name(env!("CARGO_PKG_NAME")); + .service_name(env!("CARGO_PKG_NAME")) + .register_metrics(metrics_init::register); } - metrics_init::register(); if let Err(e) = telemetry_conf .try_init() diff --git a/crates/astria-telemetry/src/lib.rs b/crates/astria-telemetry/src/lib.rs index b3e82d360..fd3268920 100644 --- a/crates/astria-telemetry/src/lib.rs +++ b/crates/astria-telemetry/src/lib.rs @@ -74,6 +74,10 @@ impl Error { fn exporter_install(source: BuildError) -> Self { Self(ErrorKind::ExporterInstall(source)) } + + fn no_metric_register_func() -> Self { + Self(ErrorKind::NoMetricRegisterFunc) + } } #[derive(Debug, thiserror::Error)] @@ -90,6 +94,11 @@ enum ErrorKind { BucketError(#[source] BuildError), #[error("failed installing prometheus metrics exporter")] ExporterInstall(#[source] BuildError), + #[error( + "telemetry was configured to run with metrics, but no function/closure to register \ + metrics was provided" + )] + NoMetricRegisterFunc, } #[must_use = "the otel config must be initialized to be useful"] @@ -136,6 +145,7 @@ pub struct Config { metrics_addr: Option, service_name: String, metric_buckets: Option>, + register_metrics: Option>, } impl Config { @@ -150,6 +160,7 @@ impl Config { metrics_addr: None, service_name: String::new(), metric_buckets: None, + register_metrics: None, } } } @@ -237,6 +248,14 @@ impl Config { } } + #[must_use = "telemetry must be initialized to be useful"] + pub fn register_metrics(self, f: F) -> Self { + Self { + register_metrics: Some(Box::new(f)), + ..self + } + } + /// Initialize telemetry, consuming the config. /// /// # Errors @@ -252,6 +271,7 @@ impl Config { metrics_addr, service_name, metric_buckets, + register_metrics, } = self; let env_filter = { @@ -322,6 +342,11 @@ impl Config { .map_err(Error::bucket_error)?; } + let Some(register_metrics) = register_metrics else { + return Err(Error::no_metric_register_func()); + }; + register_metrics(); + metrics_builder.install().map_err(Error::exporter_install)?; }