Add database size metric

This commit is contained in:
Paul Hauner
2019-06-01 14:43:08 +10:00
parent c8ba44b0b5
commit 29c5f297a6
5 changed files with 36 additions and 5 deletions

View File

@@ -128,6 +128,7 @@ where
executor, executor,
network_send, network_send,
beacon_chain.clone(), beacon_chain.clone(),
config.db_name.clone(),
metrics_registry, metrics_registry,
&log, &log,
)) ))

View File

@@ -3,6 +3,7 @@ use beacon_chain::{BeaconChain, BeaconChainTypes};
use iron::typemap::Key; use iron::typemap::Key;
use prometheus::Registry; use prometheus::Registry;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::path::PathBuf;
use std::sync::Arc; use std::sync::Arc;
pub struct BeaconChainKey<T> { pub struct BeaconChainKey<T> {
@@ -24,3 +25,9 @@ pub struct LocalMetricsKey;
impl Key for LocalMetricsKey { impl Key for LocalMetricsKey {
type Value = LocalMetrics; type Value = LocalMetrics;
} }
pub struct DBPathKey;
impl Key for DBPathKey {
type Value = PathBuf;
}

View File

@@ -9,6 +9,7 @@ use network::NetworkMessage;
use prometheus::Registry; use prometheus::Registry;
use router::Router; use router::Router;
use slog::{info, o, warn}; use slog::{info, o, warn};
use std::path::PathBuf;
use std::sync::Arc; use std::sync::Arc;
use tokio::runtime::TaskExecutor; use tokio::runtime::TaskExecutor;
@@ -32,6 +33,7 @@ impl Default for HttpServerConfig {
/// Build the `iron` HTTP server, defining the core routes. /// Build the `iron` HTTP server, defining the core routes.
pub fn create_iron_http_server<T: BeaconChainTypes + 'static>( pub fn create_iron_http_server<T: BeaconChainTypes + 'static>(
beacon_chain: Arc<BeaconChain<T>>, beacon_chain: Arc<BeaconChain<T>>,
db_path: PathBuf,
metrics_registry: Registry, metrics_registry: Registry,
) -> Iron<Router> { ) -> Iron<Router> {
let mut router = Router::new(); let mut router = Router::new();
@@ -39,7 +41,7 @@ pub fn create_iron_http_server<T: BeaconChainTypes + 'static>(
// A `GET` request to `/metrics` is handled by the `metrics` module. // A `GET` request to `/metrics` is handled by the `metrics` module.
router.get( router.get(
"/metrics", "/metrics",
metrics::build_handler(beacon_chain.clone(), metrics_registry), metrics::build_handler(beacon_chain.clone(), db_path, metrics_registry),
"metrics", "metrics",
); );
@@ -55,6 +57,7 @@ pub fn start_service<T: BeaconChainTypes + 'static>(
executor: &TaskExecutor, executor: &TaskExecutor,
_network_chan: crossbeam_channel::Sender<NetworkMessage>, _network_chan: crossbeam_channel::Sender<NetworkMessage>,
beacon_chain: Arc<BeaconChain<T>>, beacon_chain: Arc<BeaconChain<T>>,
db_path: PathBuf,
metrics_registry: Registry, metrics_registry: Registry,
log: &slog::Logger, log: &slog::Logger,
) -> exit_future::Signal { ) -> exit_future::Signal {
@@ -66,7 +69,7 @@ pub fn start_service<T: BeaconChainTypes + 'static>(
let (shutdown_trigger, wait_for_shutdown) = exit_future::signal(); let (shutdown_trigger, wait_for_shutdown) = exit_future::signal();
// Create an `iron` http, without starting it yet. // Create an `iron` http, without starting it yet.
let iron = create_iron_http_server(beacon_chain, metrics_registry); let iron = create_iron_http_server(beacon_chain, db_path, metrics_registry);
// Create a HTTP server future. // Create a HTTP server future.
// //

View File

@@ -1,5 +1,5 @@
use crate::{ use crate::{
key::{BeaconChainKey, LocalMetricsKey, MetricsRegistryKey}, key::{BeaconChainKey, DBPathKey, LocalMetricsKey, MetricsRegistryKey},
map_persistent_err_to_500, map_persistent_err_to_500,
}; };
use beacon_chain::{BeaconChain, BeaconChainTypes}; use beacon_chain::{BeaconChain, BeaconChainTypes};
@@ -7,6 +7,7 @@ use iron::prelude::*;
use iron::{status::Status, Handler, IronResult, Request, Response}; use iron::{status::Status, Handler, IronResult, Request, Response};
use persistent::Read; use persistent::Read;
use prometheus::{Encoder, Registry, TextEncoder}; use prometheus::{Encoder, Registry, TextEncoder};
use std::path::PathBuf;
use std::sync::Arc; use std::sync::Arc;
pub use local_metrics::LocalMetrics; pub use local_metrics::LocalMetrics;
@@ -16,6 +17,7 @@ mod local_metrics;
/// Yields a handler for the metrics endpoint. /// Yields a handler for the metrics endpoint.
pub fn build_handler<T: BeaconChainTypes + 'static>( pub fn build_handler<T: BeaconChainTypes + 'static>(
beacon_chain: Arc<BeaconChain<T>>, beacon_chain: Arc<BeaconChain<T>>,
db_path: PathBuf,
metrics_registry: Registry, metrics_registry: Registry,
) -> impl Handler { ) -> impl Handler {
let mut chain = Chain::new(handle_metrics::<T>); let mut chain = Chain::new(handle_metrics::<T>);
@@ -26,6 +28,7 @@ pub fn build_handler<T: BeaconChainTypes + 'static>(
chain.link(Read::<BeaconChainKey<T>>::both(beacon_chain)); chain.link(Read::<BeaconChainKey<T>>::both(beacon_chain));
chain.link(Read::<MetricsRegistryKey>::both(metrics_registry)); chain.link(Read::<MetricsRegistryKey>::both(metrics_registry));
chain.link(Read::<LocalMetricsKey>::both(local_metrics)); chain.link(Read::<LocalMetricsKey>::both(local_metrics));
chain.link(Read::<DBPathKey>::both(db_path));
chain chain
} }
@@ -46,8 +49,12 @@ fn handle_metrics<T: BeaconChainTypes + 'static>(req: &mut Request) -> IronResul
.get::<Read<LocalMetricsKey>>() .get::<Read<LocalMetricsKey>>()
.map_err(map_persistent_err_to_500)?; .map_err(map_persistent_err_to_500)?;
let db_path = req
.get::<Read<DBPathKey>>()
.map_err(map_persistent_err_to_500)?;
// Update metrics that are calculated on each scrape. // Update metrics that are calculated on each scrape.
local_metrics.update(&beacon_chain); local_metrics.update(&beacon_chain, &db_path);
let mut buffer = vec![]; let mut buffer = vec![];
let encoder = TextEncoder::new(); let encoder = TextEncoder::new();

View File

@@ -1,6 +1,8 @@
use beacon_chain::{BeaconChain, BeaconChainTypes}; use beacon_chain::{BeaconChain, BeaconChainTypes};
use prometheus::{IntGauge, Opts, Registry}; use prometheus::{IntGauge, Opts, Registry};
use slot_clock::SlotClock; use slot_clock::SlotClock;
use std::path::PathBuf;
use std::fs::File;
use types::Slot; use types::Slot;
// If set to `true` will iterate and sum the balances of all validators in the state for each // If set to `true` will iterate and sum the balances of all validators in the state for each
@@ -14,6 +16,7 @@ pub struct LocalMetrics {
justified_epoch: IntGauge, justified_epoch: IntGauge,
finalized_epoch: IntGauge, finalized_epoch: IntGauge,
validator_balances_sum: IntGauge, validator_balances_sum: IntGauge,
database_size: IntGauge,
} }
impl LocalMetrics { impl LocalMetrics {
@@ -44,6 +47,10 @@ impl LocalMetrics {
let opts = Opts::new("validator_balances_sum", "sum_of_all_validator_balances"); let opts = Opts::new("validator_balances_sum", "sum_of_all_validator_balances");
IntGauge::with_opts(opts)? IntGauge::with_opts(opts)?
}, },
database_size: {
let opts = Opts::new("database_size", "size_of_on_disk_db_in_mb");
IntGauge::with_opts(opts)?
},
}) })
} }
@@ -55,12 +62,13 @@ impl LocalMetrics {
registry.register(Box::new(self.finalized_epoch.clone()))?; registry.register(Box::new(self.finalized_epoch.clone()))?;
registry.register(Box::new(self.justified_epoch.clone()))?; registry.register(Box::new(self.justified_epoch.clone()))?;
registry.register(Box::new(self.validator_balances_sum.clone()))?; registry.register(Box::new(self.validator_balances_sum.clone()))?;
registry.register(Box::new(self.database_size.clone()))?;
Ok(()) Ok(())
} }
/// Update the metrics in `self` to the latest values. /// Update the metrics in `self` to the latest values.
pub fn update<T: BeaconChainTypes>(&self, beacon_chain: &BeaconChain<T>) { pub fn update<T: BeaconChainTypes>(&self, beacon_chain: &BeaconChain<T>, db_path: &PathBuf) {
let state = &beacon_chain.head().beacon_state; let state = &beacon_chain.head().beacon_state;
let present_slot = beacon_chain let present_slot = beacon_chain
@@ -77,5 +85,10 @@ impl LocalMetrics {
if SHOULD_SUM_VALIDATOR_BALANCES { if SHOULD_SUM_VALIDATOR_BALANCES {
self.validator_balances_sum.set(state.validator_balances.iter().sum::<u64>() as i64); self.validator_balances_sum.set(state.validator_balances.iter().sum::<u64>() as i64);
} }
let db_size = File::open(db_path)
.and_then(|f| f.metadata())
.and_then(|m| Ok(m.len()))
.unwrap_or(0);
self.database_size.set(db_size as i64);
} }
} }