Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove lazy_static, use ServiceMetrics struct instead #4

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

168 changes: 97 additions & 71 deletions client/service/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<U64>,
best_height: Gauge<U64>,
peers_num: Gauge<U64>,
tx_count: Gauge<U64>,
node_memory: Gauge<U64>,
node_cpu: Gauge<F64>,
node_download: Gauge<U64>,
node_upload: Gauge<U64>,
sync_target: Gauge<U64>,
}

prometheus_exporter::lazy_static! {
pub static ref FINALITY_HEIGHT: Gauge<U64> = create_gauge(
"finality_block_height_number",
"Height of the highest finalized block"
);
pub static ref BEST_HEIGHT: Gauge<U64> = create_gauge(
"best_block_height_number",
"Height of the highest block"
);
pub static ref PEERS_NUM: Gauge<U64> = create_gauge(
"peers_count",
"Number of network gossip peers"
);
pub static ref TX_COUNT: Gauge<U64> = create_gauge(
"transaction_count",
"Number of transactions"
);
pub static ref NODE_MEMORY: Gauge<U64> = create_gauge(
"memory_usage",
"Node memory usage"
);
pub static ref NODE_CPU: Gauge<F64> = create_gauge(
"cpu_usage",
"Node CPU usage"
);
pub static ref NODE_DOWNLOAD: Gauge<U64> = create_gauge(
"receive_byte_per_sec",
"Received bytes per second"
);
pub static ref NODE_UPLOAD: Gauge<U64> = create_gauge(
"sent_byte_per_sec",
"Sent bytes per second"
);
pub static ref SYNC_TARGET: Gauge<U64> = create_gauge(
"sync_target_number",
"Block sync target number"
);
impl ServiceMetrics {
fn register(registry: &Registry) -> Result<Self, PrometheusError> {
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
Expand Down Expand Up @@ -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(&registry)?;

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();
Expand Down Expand Up @@ -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(())
Expand Down Expand Up @@ -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() {
Expand Down
1 change: 0 additions & 1 deletion utils/prometheus/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
18 changes: 8 additions & 10 deletions utils/prometheus/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@
// You should have received a copy of the GNU General Public License
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.

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}};
Expand All @@ -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<T: Atomic + 'static>(name: &str, description: &str) -> Gauge<T> {
let opts = Opts::new(name, description);
let gauge = Gauge::with_opts(opts).expect("Creating Gauge Failed");
gauge
pub fn create_gauge<T: Atomic + 'static>(name: &str, description: &str, registry: &Registry) -> Result<Gauge<T>, 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)]
Expand All @@ -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 {
Expand Down