diff --git a/beacon_node/http_server/src/metrics.rs b/beacon_node/http_server/src/metrics.rs index bfa80ec55..7e716d5d7 100644 --- a/beacon_node/http_server/src/metrics.rs +++ b/beacon_node/http_server/src/metrics.rs @@ -6,10 +6,12 @@ use beacon_chain::{BeaconChain, BeaconChainTypes}; use iron::prelude::*; use iron::{status::Status, Handler, IronResult, Request, Response}; use persistent::Read; -use prometheus::{Encoder, IntGauge, Opts, Registry, TextEncoder}; -use slot_clock::SlotClock; +use prometheus::{Encoder, Registry, TextEncoder}; use std::sync::Arc; -use types::Slot; + +pub use local_metrics::LocalMetrics; + +mod local_metrics; /// Yields a handler for the metrics endpoint. pub fn build_handler( @@ -28,39 +30,6 @@ pub fn build_handler( chain } -pub struct LocalMetrics { - present_slot: IntGauge, - best_slot: IntGauge, - validator_count: IntGauge, -} - -impl LocalMetrics { - pub fn new() -> Result { - Ok(Self { - present_slot: { - let opts = Opts::new("present_slot", "slot_at_time_of_scrape"); - IntGauge::with_opts(opts)? - }, - best_slot: { - let opts = Opts::new("best_slot", "slot_of_block_at_chain_head"); - IntGauge::with_opts(opts)? - }, - validator_count: { - let opts = Opts::new("validator_count", "number_of_validators"); - IntGauge::with_opts(opts)? - }, - }) - } - - pub fn register(&self, registry: &Registry) -> Result<(), prometheus::Error> { - registry.register(Box::new(self.present_slot.clone()))?; - registry.register(Box::new(self.best_slot.clone()))?; - registry.register(Box::new(self.validator_count.clone()))?; - - Ok(()) - } -} - /// Handle a request for Prometheus metrics. /// /// Returns a text string containing all metrics. @@ -77,18 +46,8 @@ fn handle_metrics(req: &mut Request) -> IronResul .get::>() .map_err(map_persistent_err_to_500)?; - let present_slot = beacon_chain - .slot_clock - .present_slot() - .unwrap_or_else(|_| None) - .unwrap_or_else(|| Slot::new(0)); - local_metrics.present_slot.set(present_slot.as_u64() as i64); - - let best_slot = beacon_chain.head().beacon_block.slot; - local_metrics.best_slot.set(best_slot.as_u64() as i64); - - let validator_count = beacon_chain.head().beacon_state.validator_registry.len(); - local_metrics.validator_count.set(validator_count as i64); + // Update metrics that are calculated on each scrape. + local_metrics.update(&beacon_chain); let mut buffer = vec![]; let encoder = TextEncoder::new(); diff --git a/beacon_node/http_server/src/metrics/local_metrics.rs b/beacon_node/http_server/src/metrics/local_metrics.rs new file mode 100644 index 000000000..8b9b1fdad --- /dev/null +++ b/beacon_node/http_server/src/metrics/local_metrics.rs @@ -0,0 +1,66 @@ +use beacon_chain::{BeaconChain, BeaconChainTypes}; +use prometheus::{IntGauge, Opts, Registry}; +use slot_clock::SlotClock; +use types::Slot; + +pub struct LocalMetrics { + present_slot: IntGauge, + best_slot: IntGauge, + validator_count: IntGauge, + justified_epoch: IntGauge, + finalized_epoch: IntGauge, +} + +impl LocalMetrics { + /// Create a new instance. + pub fn new() -> Result { + Ok(Self { + present_slot: { + let opts = Opts::new("present_slot", "slot_at_time_of_scrape"); + IntGauge::with_opts(opts)? + }, + best_slot: { + let opts = Opts::new("best_slot", "slot_of_block_at_chain_head"); + IntGauge::with_opts(opts)? + }, + validator_count: { + let opts = Opts::new("validator_count", "number_of_validators"); + IntGauge::with_opts(opts)? + }, + justified_epoch: { + let opts = Opts::new("justified_epoch", "state_justified_epoch"); + IntGauge::with_opts(opts)? + }, + finalized_epoch: { + let opts = Opts::new("finalized_epoch", "state_finalized_epoch"); + IntGauge::with_opts(opts)? + }, + }) + } + + /// Registry this instance with the `registry`. + pub fn register(&self, registry: &Registry) -> Result<(), prometheus::Error> { + registry.register(Box::new(self.present_slot.clone()))?; + registry.register(Box::new(self.best_slot.clone()))?; + registry.register(Box::new(self.validator_count.clone()))?; + + Ok(()) + } + + /// Update the metrics in `self` to the latest values. + pub fn update(&self, beacon_chain: &BeaconChain) { + let state = &beacon_chain.head().beacon_state; + + let present_slot = beacon_chain + .slot_clock + .present_slot() + .unwrap_or_else(|_| None) + .unwrap_or_else(|| Slot::new(0)); + self.present_slot.set(present_slot.as_u64() as i64); + + self.best_slot.set(state.slot.as_u64() as i64); + self.validator_count.set(state.validator_registry.len() as i64); + self.justified_epoch.set(state.current_justified_epoch.as_u64() as i64); + self.finalized_epoch.set(state.finalized_epoch.as_u64() as i64); + } +}