use datasize::DataSize;
use prometheus::{self, Histogram, HistogramOpts, IntGauge, Registry};
use tracing::debug;
use super::Reactor;
#[derive(Debug)]
pub(super) struct MemoryMetrics {
mem_total: IntGauge,
mem_metrics: IntGauge,
mem_net: IntGauge,
mem_address_gossiper: IntGauge,
mem_storage: IntGauge,
mem_contract_runtime: IntGauge,
mem_rpc_server: IntGauge,
mem_rest_server: IntGauge,
mem_event_stream_server: IntGauge,
mem_chainspec_loader: IntGauge,
mem_consensus: IntGauge,
mem_deploy_fetcher: IntGauge,
mem_deploy_gossiper: IntGauge,
mem_block_proposer: IntGauge,
mem_block_executor: IntGauge,
mem_proto_block_validator: IntGauge,
mem_linear_chain: IntGauge,
mem_estimator_runtime_s: Histogram,
registry: Registry,
}
impl MemoryMetrics {
pub(super) fn new(registry: Registry) -> Result<Self, prometheus::Error> {
let mem_total = IntGauge::new("mem_total", "total memory usage in bytes")?;
let mem_metrics = IntGauge::new("mem_metrics", "metrics memory usage in bytes")?;
let mem_net = IntGauge::new("mem_net", "net memory usage in bytes")?;
let mem_address_gossiper = IntGauge::new(
"mem_address_gossiper",
"address_gossiper memory usage in bytes",
)?;
let mem_storage = IntGauge::new("mem_storage", "storage memory usage in bytes")?;
let mem_contract_runtime = IntGauge::new(
"mem_contract_runtime",
"contract_runtime memory usage in bytes",
)?;
let mem_rpc_server = IntGauge::new("mem_rpc_server", "rpc_server memory usage in bytes")?;
let mem_rest_server =
IntGauge::new("mem_rest_server", "mem_rest_server memory usage in bytes")?;
let mem_event_stream_server = IntGauge::new(
"mem_event_stream_server",
"mem_event_stream_server memory usage in bytes",
)?;
let mem_chainspec_loader = IntGauge::new(
"mem_chainspec_loader",
"chainspec_loader memory usage in bytes",
)?;
let mem_consensus = IntGauge::new("mem_consensus", "consensus memory usage in bytes")?;
let mem_deploy_fetcher =
IntGauge::new("mem_deploy_fetcher", "deploy_fetcher memory usage in bytes")?;
let mem_deploy_gossiper = IntGauge::new(
"mem_deploy_gossiper",
"deploy_gossiper memory usage in bytes",
)?;
let mem_block_proposer =
IntGauge::new("mem_block_proposer", "block_proposer memory usage in bytes")?;
let mem_block_executor =
IntGauge::new("mem_block_executor", "block_executor memory usage in bytes")?;
let mem_proto_block_validator = IntGauge::new(
"mem_proto_block_validator",
"proto_block_validator memory usage in bytes",
)?;
let mem_linear_chain =
IntGauge::new("mem_linear_chain", "linear_chain memory usage in bytes")?;
let mem_estimator_runtime_s = Histogram::with_opts(
HistogramOpts::new(
"mem_estimator_runtime_s",
"time taken to estimate memory usage, in seconds",
)
.buckets(prometheus::exponential_buckets(0.000_000_004, 2.0, 32)?),
)?;
registry.register(Box::new(mem_total.clone()))?;
registry.register(Box::new(mem_metrics.clone()))?;
registry.register(Box::new(mem_net.clone()))?;
registry.register(Box::new(mem_address_gossiper.clone()))?;
registry.register(Box::new(mem_storage.clone()))?;
registry.register(Box::new(mem_contract_runtime.clone()))?;
registry.register(Box::new(mem_rpc_server.clone()))?;
registry.register(Box::new(mem_rest_server.clone()))?;
registry.register(Box::new(mem_event_stream_server.clone()))?;
registry.register(Box::new(mem_chainspec_loader.clone()))?;
registry.register(Box::new(mem_consensus.clone()))?;
registry.register(Box::new(mem_deploy_fetcher.clone()))?;
registry.register(Box::new(mem_deploy_gossiper.clone()))?;
registry.register(Box::new(mem_block_proposer.clone()))?;
registry.register(Box::new(mem_block_executor.clone()))?;
registry.register(Box::new(mem_proto_block_validator.clone()))?;
registry.register(Box::new(mem_linear_chain.clone()))?;
registry.register(Box::new(mem_estimator_runtime_s.clone()))?;
Ok(MemoryMetrics {
mem_total,
mem_metrics,
mem_net,
mem_address_gossiper,
mem_storage,
mem_contract_runtime,
mem_rpc_server,
mem_rest_server,
mem_event_stream_server,
mem_chainspec_loader,
mem_consensus,
mem_deploy_fetcher,
mem_deploy_gossiper,
mem_block_proposer,
mem_block_executor,
mem_proto_block_validator,
mem_linear_chain,
mem_estimator_runtime_s,
registry,
})
}
pub(super) fn estimate(&self, reactor: &Reactor) {
let timer = self.mem_estimator_runtime_s.start_timer();
let metrics = reactor.metrics.estimate_heap_size() as i64;
let net = reactor.small_network.estimate_heap_size() as i64;
let address_gossiper = reactor.address_gossiper.estimate_heap_size() as i64;
let storage = reactor.storage.estimate_heap_size() as i64;
let contract_runtime = reactor.contract_runtime.estimate_heap_size() as i64;
let rpc_server = reactor.rpc_server.estimate_heap_size() as i64;
let rest_server = reactor.rest_server.estimate_heap_size() as i64;
let event_stream_server = reactor.event_stream_server.estimate_heap_size() as i64;
let chainspec_loader = reactor.chainspec_loader.estimate_heap_size() as i64;
let consensus = reactor.consensus.estimate_heap_size() as i64;
let deploy_fetcher = reactor.deploy_fetcher.estimate_heap_size() as i64;
let deploy_gossiper = reactor.deploy_gossiper.estimate_heap_size() as i64;
let block_proposer = reactor.block_proposer.estimate_heap_size() as i64;
let block_executor = reactor.block_executor.estimate_heap_size() as i64;
let proto_block_validator = reactor.proto_block_validator.estimate_heap_size() as i64;
let linear_chain = reactor.linear_chain.estimate_heap_size() as i64;
let total = metrics
+ net
+ address_gossiper
+ storage
+ contract_runtime
+ rpc_server
+ rest_server
+ event_stream_server
+ chainspec_loader
+ consensus
+ deploy_fetcher
+ deploy_gossiper
+ block_proposer
+ block_executor
+ proto_block_validator
+ linear_chain;
self.mem_total.set(total);
self.mem_metrics.set(metrics);
self.mem_net.set(net);
self.mem_address_gossiper.set(address_gossiper);
self.mem_storage.set(storage);
self.mem_contract_runtime.set(contract_runtime);
self.mem_rpc_server.set(rpc_server);
self.mem_rest_server.set(rest_server);
self.mem_event_stream_server.set(event_stream_server);
self.mem_chainspec_loader.set(chainspec_loader);
self.mem_consensus.set(consensus);
self.mem_deploy_fetcher.set(deploy_fetcher);
self.mem_deploy_gossiper.set(deploy_gossiper);
self.mem_block_proposer.set(block_proposer);
self.mem_block_executor.set(block_executor);
self.mem_proto_block_validator.set(proto_block_validator);
self.mem_linear_chain.set(linear_chain);
let duration_s = timer.stop_and_record();
debug!(%total,
%duration_s,
%metrics,
%net,
%address_gossiper,
%storage,
%contract_runtime,
%rpc_server,
%rest_server,
%event_stream_server,
%chainspec_loader,
%consensus,
%deploy_fetcher,
%deploy_gossiper,
%block_proposer,
%block_executor,
%proto_block_validator,
%linear_chain,
"Collected new set of memory metrics.");
}
}
impl Drop for MemoryMetrics {
fn drop(&mut self) {
self.registry
.unregister(Box::new(self.mem_total.clone()))
.expect("did not expect deregistering mem_total, to fail");
self.registry
.unregister(Box::new(self.mem_metrics.clone()))
.expect("did not expect deregistering mem_metrics, to fail");
self.registry
.unregister(Box::new(self.mem_net.clone()))
.expect("did not expect deregistering mem_net, to fail");
self.registry
.unregister(Box::new(self.mem_address_gossiper.clone()))
.expect("did not expect deregistering mem_address_gossiper, to fail");
self.registry
.unregister(Box::new(self.mem_storage.clone()))
.expect("did not expect deregistering mem_storage, to fail");
self.registry
.unregister(Box::new(self.mem_contract_runtime.clone()))
.expect("did not expect deregistering mem_contract_runtime, to fail");
self.registry
.unregister(Box::new(self.mem_rpc_server.clone()))
.expect("did not expect deregistering mem_rpc_server, to fail");
self.registry
.unregister(Box::new(self.mem_rest_server.clone()))
.expect("did not expect deregistering mem_rest_server, to fail");
self.registry
.unregister(Box::new(self.mem_event_stream_server.clone()))
.expect("did not expect deregistering mem_event_stream_server, to fail");
self.registry
.unregister(Box::new(self.mem_chainspec_loader.clone()))
.expect("did not expect deregistering mem_chainspec_loader, to fail");
self.registry
.unregister(Box::new(self.mem_consensus.clone()))
.expect("did not expect deregistering mem_consensus, to fail");
self.registry
.unregister(Box::new(self.mem_deploy_fetcher.clone()))
.expect("did not expect deregistering mem_deploy_fetcher, to fail");
self.registry
.unregister(Box::new(self.mem_deploy_gossiper.clone()))
.expect("did not expect deregistering mem_deploy_gossiper, to fail");
self.registry
.unregister(Box::new(self.mem_block_proposer.clone()))
.expect("did not expect deregistering mem_block_proposer, to fail");
self.registry
.unregister(Box::new(self.mem_block_executor.clone()))
.expect("did not expect deregistering mem_block_executor, to fail");
self.registry
.unregister(Box::new(self.mem_proto_block_validator.clone()))
.expect("did not expect deregistering mem_proto_block_validator, to fail");
self.registry
.unregister(Box::new(self.mem_linear_chain.clone()))
.expect("did not expect deregistering mem_linear_chain, to fail");
}
}