From d2bba611438f5c5c379968eb42fcc1cf5d94ecbf Mon Sep 17 00:00:00 2001 From: Ashley Date: Tue, 21 Jan 2020 14:53:28 +0100 Subject: [PATCH] Remove lazy_static, use ServiceMetrics struct instead --- Cargo.lock | 1 - client/service/src/builder.rs | 168 ++++++++++++++++++++-------------- utils/prometheus/Cargo.toml | 1 - utils/prometheus/src/lib.rs | 18 ++-- 4 files changed, 105 insertions(+), 83 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b8df759cf4087..86d274da59b81 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4500,7 +4500,6 @@ dependencies = [ "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", "futures-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "prometheus 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/client/service/src/builder.rs b/client/service/src/builder.rs index 85d4091eed02b..ec336de37de32 100644 --- a/client/service/src/builder.rs +++ b/client/service/src/builder.rs @@ -51,46 +51,72 @@ use sysinfo::{get_current_pid, ProcessExt, System, SystemExt}; use sc_telemetry::{telemetry, SUBSTRATE_INFO}; use sp_transaction_pool::{TransactionPool, TransactionPoolMaintainer}; use sp_blockchain; -use prometheus_exporter::{create_gauge, Gauge, U64, F64, Registry}; +use prometheus_exporter::{create_gauge, Gauge, U64, F64, Registry, PrometheusError}; + +struct ServiceMetrics { + finality_height: Gauge, + best_height: Gauge, + peers_num: Gauge, + tx_count: Gauge, + node_memory: Gauge, + node_cpu: Gauge, + node_download: Gauge, + node_upload: Gauge, + sync_target: Gauge, +} -prometheus_exporter::lazy_static! { - pub static ref FINALITY_HEIGHT: Gauge = create_gauge( - "finality_block_height_number", - "Height of the highest finalized block" - ); - pub static ref BEST_HEIGHT: Gauge = create_gauge( - "best_block_height_number", - "Height of the highest block" - ); - pub static ref PEERS_NUM: Gauge = create_gauge( - "peers_count", - "Number of network gossip peers" - ); - pub static ref TX_COUNT: Gauge = create_gauge( - "transaction_count", - "Number of transactions" - ); - pub static ref NODE_MEMORY: Gauge = create_gauge( - "memory_usage", - "Node memory usage" - ); - pub static ref NODE_CPU: Gauge = create_gauge( - "cpu_usage", - "Node CPU usage" - ); - pub static ref NODE_DOWNLOAD: Gauge = create_gauge( - "receive_byte_per_sec", - "Received bytes per second" - ); - pub static ref NODE_UPLOAD: Gauge = create_gauge( - "sent_byte_per_sec", - "Sent bytes per second" - ); - pub static ref SYNC_TARGET: Gauge = create_gauge( - "sync_target_number", - "Block sync target number" - ); +impl ServiceMetrics { + fn register(registry: &Registry) -> Result { + Ok(Self { + finality_height: create_gauge( + "finality_block_height_number", + "Height of the highest finalized block", + registry + )?, + best_height: create_gauge( + "best_block_height_number", + "Height of the highest block", + registry + )?, + peers_num: create_gauge( + "peers_count", + "Number of network gossip peers", + registry + )?, + tx_count: create_gauge( + "transaction_count", + "Number of transactions", + registry + )?, + node_memory: create_gauge( + "memory_usage", + "Node memory usage", + registry + )?, + node_cpu: create_gauge( + "cpu_usage", + "Node CPU usage", + registry + )?, + node_download: create_gauge( + "receive_byte_per_sec", + "Received bytes per second", + registry + )?, + node_upload: create_gauge( + "sent_byte_per_sec", + "Sent bytes per second", + registry + )?, + sync_target: create_gauge( + "sync_target_number", + "Block sync target number", + registry + )?, + }) + } } + /// Aggregator for the components required to build a service. /// /// # Usage @@ -993,6 +1019,27 @@ ServiceBuilder< let _ = to_spawn_tx.unbounded_send(Box::pin(select(events, exit.clone()).map(drop))); } + // Prometheus exporter and metrics + let metrics = if let Some(port) = config.prometheus_port { + let registry = match prometheus_registry { + Some(registry) => registry, + None => Registry::new_custom(Some("substrate".into()), None)? + }; + + let metrics = ServiceMetrics::register(®istry)?; + + let future = select( + prometheus_exporter::init_prometheus(port, registry).boxed(), + exit.clone() + ).map(drop); + + let _ = to_spawn_tx.unbounded_send(Box::pin(future)); + + Some(metrics) + } else { + None + }; + // Periodically notify the telemetry. let transaction_pool_ = transaction_pool.clone(); let client_ = client.clone(); @@ -1039,16 +1086,18 @@ ServiceBuilder< "disk_read_per_sec" => info.usage.as_ref().map(|usage| usage.io.bytes_read).unwrap_or(0), "disk_write_per_sec" => info.usage.as_ref().map(|usage| usage.io.bytes_written).unwrap_or(0), ); - NODE_MEMORY.set(memory); - NODE_CPU.set(f64::from(cpu_usage)); - TX_COUNT.set(txpool_status.ready as u64); - FINALITY_HEIGHT.set(finalized_number); - BEST_HEIGHT.set(best_number); - PEERS_NUM.set(num_peers as u64); - NODE_DOWNLOAD.set(net_status.average_download_per_sec); - NODE_UPLOAD.set(net_status.average_upload_per_sec); - if let Some(best_seen_block) = best_seen_block { - SYNC_TARGET.set(best_seen_block); + if let Some(metrics) = metrics.as_ref() { + metrics.node_memory.set(memory); + metrics.node_cpu.set(f64::from(cpu_usage)); + metrics.tx_count.set(txpool_status.ready as u64); + metrics.finality_height.set(finalized_number); + metrics.best_height.set(best_number); + metrics.peers_num.set(num_peers as u64); + metrics.node_download.set(net_status.average_download_per_sec); + metrics.node_upload.set(net_status.average_upload_per_sec); + if let Some(best_seen_block) = best_seen_block { + metrics.sync_target.set(best_seen_block); + } } ready(()) @@ -1182,29 +1231,6 @@ ServiceBuilder< ).map(drop))); telemetry }); - // Prometheus exporter - if let Some(port) = config.prometheus_port { - let registry = match prometheus_registry { - Some(registry) => registry, - None => Registry::new_custom(Some("substrate".into()), None)? - }; - - registry.register(Box::new(NODE_MEMORY.clone()))?; - registry.register(Box::new(NODE_CPU.clone()))?; - registry.register(Box::new(TX_COUNT.clone()))?; - registry.register(Box::new(FINALITY_HEIGHT.clone()))?; - registry.register(Box::new(BEST_HEIGHT.clone()))?; - registry.register(Box::new(PEERS_NUM.clone()))?; - registry.register(Box::new(NODE_DOWNLOAD.clone()))?; - registry.register(Box::new(NODE_UPLOAD.clone()))?; - - let future = select( - prometheus_exporter::init_prometheus(port, registry).boxed(), - exit.clone() - ).map(drop); - - let _ = to_spawn_tx.unbounded_send(Box::pin(future)); - } // Instrumentation if let Some(tracing_targets) = config.tracing_targets.as_ref() { diff --git a/utils/prometheus/Cargo.toml b/utils/prometheus/Cargo.toml index d335505d58cfe..8e50b4024e3bc 100644 --- a/utils/prometheus/Cargo.toml +++ b/utils/prometheus/Cargo.toml @@ -12,7 +12,6 @@ hyper = { version = "0.13.1", default-features = false, features = ["stream"] } prometheus = { version = "0.7", features = ["nightly", "process"]} tokio = "0.2" futures-util = { version = "0.3.1", default-features = false, features = ["io"] } -lazy_static = "1.4" derive_more = "0.99" [target.'cfg(not(target_os = "unknown"))'.dependencies] diff --git a/utils/prometheus/src/lib.rs b/utils/prometheus/src/lib.rs index fc53d89ba0301..25f058acc377d 100644 --- a/utils/prometheus/src/lib.rs +++ b/utils/prometheus/src/lib.rs @@ -14,8 +14,6 @@ // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . -extern crate lazy_static; - use futures_util::{FutureExt, future::Future}; use hyper::http::StatusCode; use hyper::{Server, Body, Response, service::{service_fn, make_service_fn}}; @@ -24,16 +22,15 @@ use std::net::SocketAddr; #[cfg(not(target_os = "unknown"))] mod networking; -pub use prometheus::core::{ - GenericGauge as Gauge, AtomicF64 as F64, AtomicI64 as I64, AtomicU64 as U64 +pub use prometheus::{ + Registry, Error as PrometheusError, + core::{GenericGauge as Gauge, AtomicF64 as F64, AtomicI64 as I64, AtomicU64 as U64} }; -pub use prometheus::{Registry, Error as PrometheusError}; -pub use lazy_static::lazy_static; -pub fn create_gauge(name: &str, description: &str) -> Gauge { - let opts = Opts::new(name, description); - let gauge = Gauge::with_opts(opts).expect("Creating Gauge Failed"); - gauge +pub fn create_gauge(name: &str, description: &str, registry: &Registry) -> Result, PrometheusError> { + let gauge = Gauge::with_opts(Opts::new(name, description))?; + registry.register(Box::new(gauge.clone()))?; + Ok(gauge) } #[derive(Debug, derive_more::Display, derive_more::From)] @@ -47,6 +44,7 @@ pub enum Error { #[display(fmt = "Prometheus exporter port {} already in use.", _0)] PortInUse(SocketAddr) } + impl std::error::Error for Error { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { match self {