diff --git a/Cargo.lock b/Cargo.lock index 4eafe2b239a..baad82c4a35 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1344,7 +1344,6 @@ dependencies = [ "apollo_mempool", "apollo_mempool_p2p", "apollo_metrics", - "apollo_monitoring_endpoint", "apollo_network", "apollo_state_sync_metrics", "apollo_storage", diff --git a/crates/apollo_dashboard/Cargo.toml b/crates/apollo_dashboard/Cargo.toml index 99e02bb5ab0..21bed56f1a0 100644 --- a/crates/apollo_dashboard/Cargo.toml +++ b/crates/apollo_dashboard/Cargo.toml @@ -31,7 +31,6 @@ apollo_l1_provider.workspace = true apollo_mempool.workspace = true apollo_mempool_p2p.workspace = true apollo_metrics.workspace = true -apollo_monitoring_endpoint.workspace = true apollo_network.workspace = true apollo_state_sync_metrics.workspace = true apollo_storage.workspace = true diff --git a/crates/apollo_dashboard/src/alert_scenarios/transaction_delays.rs b/crates/apollo_dashboard/src/alert_scenarios/transaction_delays.rs index ecf9f66a39c..3830863708f 100644 --- a/crates/apollo_dashboard/src/alert_scenarios/transaction_delays.rs +++ b/crates/apollo_dashboard/src/alert_scenarios/transaction_delays.rs @@ -1,8 +1,8 @@ use apollo_batcher::metrics::NUM_TRANSACTION_IN_BLOCK; use apollo_http_server::metrics::HTTP_SERVER_ADD_TX_LATENCY; +use apollo_infra::metrics::HISTOGRAM_BUCKETS; use apollo_mempool_p2p::metrics::MEMPOOL_P2P_NUM_CONNECTED_PEERS; use apollo_metrics::metrics::MetricQueryName; -use apollo_monitoring_endpoint::monitoring_endpoint::HISTOGRAM_BUCKETS; use crate::alerts::{ Alert, diff --git a/crates/apollo_infra/Cargo.toml b/crates/apollo_infra/Cargo.toml index ab93a37fadb..8b8394bee51 100644 --- a/crates/apollo_infra/Cargo.toml +++ b/crates/apollo_infra/Cargo.toml @@ -18,6 +18,7 @@ apollo_infra_utils.workspace = true apollo_metrics.workspace = true async-trait.workspace = true hyper = { workspace = true, features = ["client", "http2", "server", "tcp"] } +metrics-exporter-prometheus.workspace = true rstest.workspace = true serde = { workspace = true, features = ["derive"] } serde_json.workspace = true diff --git a/crates/apollo_infra/src/metrics.rs b/crates/apollo_infra/src/metrics.rs index 0d269d37422..49ed546d2d4 100644 --- a/crates/apollo_infra/src/metrics.rs +++ b/crates/apollo_infra/src/metrics.rs @@ -3,10 +3,18 @@ use apollo_metrics::metrics::{ MetricCounter, MetricGauge, MetricHistogram, + COLLECT_SEQUENCER_PROFILING_METRICS, }; +use metrics_exporter_prometheus::{PrometheusBuilder, PrometheusHandle}; use serde::{Deserialize, Serialize}; use crate::requests::LABEL_NAME_REQUEST_VARIANT; +use crate::tokio_metrics::setup_tokio_metrics; + +pub const HISTOGRAM_BUCKETS: &[f64] = &[ + 0.001, 0.0025, 0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1.0, 2.5, 5.0, 10.0, 25.0, 50.0, + 100.0, 250.0, +]; /// Configuration for metrics collection. #[derive(Clone, Copy, Debug, Default, Serialize, Deserialize, PartialEq)] @@ -29,6 +37,45 @@ impl MetricsConfig { } } +/// Initializes the metrics recorder and tokio metrics if metrics collection is enabled. +/// This should be called once during application startup, before creating components that use +/// metrics. +/// +/// Returns a PrometheusHandle if metrics collection is enabled, None otherwise. +/// +/// # Example +/// ```no_run +/// use apollo_infra::metrics::{initialize_metrics_recorder, MetricsConfig}; +/// +/// let config = MetricsConfig::enabled(); +/// let prometheus_handle = initialize_metrics_recorder(config); +/// ``` +pub fn initialize_metrics_recorder(config: MetricsConfig) -> Option { + // TODO(Tsabary): consider error handling + let prometheus_handle = if config.collect_metrics { + // TODO(Lev): add tests that show the metrics are collected / not collected based on the + // config value. + COLLECT_SEQUENCER_PROFILING_METRICS + .set(config.collect_profiling_metrics) + .expect("Should be able to set profiling metrics collection."); + + Some( + PrometheusBuilder::new() + .set_buckets(HISTOGRAM_BUCKETS) + .expect("Should be able to set buckets") + .install_recorder() + .expect("should be able to build the recorder and install it globally"), + ) + } else { + None + }; + + // Setup tokio metrics along with other metrics initialization + setup_tokio_metrics(); + + prometheus_handle +} + /// Metrics of a local client. #[derive(Clone)] pub struct LocalClientMetrics { diff --git a/crates/apollo_infra/src/tokio_metrics.rs b/crates/apollo_infra/src/tokio_metrics.rs index 373ec31b6ed..1bce80aabfa 100644 --- a/crates/apollo_infra/src/tokio_metrics.rs +++ b/crates/apollo_infra/src/tokio_metrics.rs @@ -26,7 +26,7 @@ define_metrics!( /// Start the tokio runtime metrics reporter to automatically collect and export tokio runtime /// metrics -pub fn setup_tokio_metrics() { +pub(crate) fn setup_tokio_metrics() { tokio::spawn( RuntimeMetricsReporterBuilder::default() .with_interval(Duration::from_secs(TOKIO_REPORTING_INTERVAL_SECONDS)) diff --git a/crates/apollo_monitoring_endpoint/src/monitoring_endpoint.rs b/crates/apollo_monitoring_endpoint/src/monitoring_endpoint.rs index 722f32193be..9d397f3fa3d 100644 --- a/crates/apollo_monitoring_endpoint/src/monitoring_endpoint.rs +++ b/crates/apollo_monitoring_endpoint/src/monitoring_endpoint.rs @@ -1,14 +1,12 @@ use std::net::SocketAddr; use apollo_infra::component_definitions::ComponentStarter; -use apollo_infra::metrics::MetricsConfig; -use apollo_infra::tokio_metrics::setup_tokio_metrics; +use apollo_infra::metrics::{initialize_metrics_recorder, MetricsConfig}; use apollo_infra::trace_util::{configure_tracing, get_log_directives, set_log_level}; use apollo_infra_utils::type_name::short_type_name; use apollo_l1_provider_types::{L1ProviderSnapshot, SharedL1ProviderClient}; use apollo_mempool_types::communication::SharedMempoolClient; use apollo_mempool_types::mempool_types::MempoolSnapshot; -use apollo_metrics::metrics::COLLECT_SEQUENCER_PROFILING_METRICS; use apollo_monitoring_endpoint_config::config::MonitoringEndpointConfig; use axum::extract::Path; use axum::http::StatusCode; @@ -16,7 +14,7 @@ use axum::response::{IntoResponse, Response}; use axum::routing::{get, post}; use axum::{async_trait, Json, Router, Server}; use hyper::Error; -use metrics_exporter_prometheus::{PrometheusBuilder, PrometheusHandle}; +use metrics_exporter_prometheus::PrometheusHandle; use tracing::level_filters::LevelFilter; use tracing::{error, info, instrument}; @@ -34,11 +32,6 @@ pub(crate) const L1_PROVIDER_SNAPSHOT: &str = "l1ProviderSnapshot"; pub(crate) const SET_LOG_LEVEL: &str = "setLogLevel"; pub(crate) const LOG_LEVEL: &str = "logLevel"; -pub const HISTOGRAM_BUCKETS: &[f64] = &[ - 0.001, 0.0025, 0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1.0, 2.5, 5.0, 10.0, 25.0, 50.0, - 100.0, 250.0, -]; - pub struct MonitoringEndpoint { config: MonitoringEndpointConfig, version: &'static str, @@ -51,28 +44,10 @@ impl MonitoringEndpoint { pub fn new( config: MonitoringEndpointConfig, version: &'static str, - metrics_config: MetricsConfig, + prometheus_handle: Option, mempool_client: Option, l1_provider_client: Option, ) -> Self { - // TODO(Tsabary): consider error handling - let prometheus_handle = if metrics_config.collect_metrics { - // TODO(Lev): add tests that show the metrics are collected / not collected based on the - // config value. - COLLECT_SEQUENCER_PROFILING_METRICS - .set(metrics_config.collect_profiling_metrics) - .expect("Should be able to set profiling metrics collection."); - - Some( - PrometheusBuilder::new() - .set_buckets(HISTOGRAM_BUCKETS) - .expect("Should be able to set buckets") - .install_recorder() - .expect("should be able to build the recorder and install it globally"), - ) - } else { - None - }; MonitoringEndpoint { config, version, @@ -141,8 +116,6 @@ impl MonitoringEndpoint { } } -// TODO(tsabary): finalize the separation of the metrics recorder initialization and the monitoring -// endpoint setup pub fn create_monitoring_endpoint( config: MonitoringEndpointConfig, version: &'static str, @@ -150,15 +123,8 @@ pub fn create_monitoring_endpoint( mempool_client: Option, l1_provider_client: Option, ) -> MonitoringEndpoint { - let result = MonitoringEndpoint::new( - config, - version, - metrics_config, - mempool_client, - l1_provider_client, - ); - setup_tokio_metrics(); - result + let prometheus_handle = initialize_metrics_recorder(metrics_config); + MonitoringEndpoint::new(config, version, prometheus_handle, mempool_client, l1_provider_client) } #[async_trait]