mirror of
https://github.com/paradigmxyz/reth.git
synced 2026-04-30 03:01:58 -04:00
feat: add DatabaseMetrics trait for generic DB in reth node (#5690)
This commit is contained in:
14
crates/storage/db/src/abstraction/database_metrics.rs
Normal file
14
crates/storage/db/src/abstraction/database_metrics.rs
Normal file
@@ -0,0 +1,14 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
/// Represents a type that can report metrics, used mainly with the database. The `report_metrics`
|
||||
/// method can be used as a prometheus hook.
|
||||
pub trait DatabaseMetrics {
|
||||
/// Reports metrics for the database.
|
||||
fn report_metrics(&self);
|
||||
}
|
||||
|
||||
impl<DB: DatabaseMetrics> DatabaseMetrics for Arc<DB> {
|
||||
fn report_metrics(&self) {
|
||||
<DB as DatabaseMetrics>::report_metrics(self)
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,8 @@ pub mod common;
|
||||
pub mod cursor;
|
||||
/// Database traits.
|
||||
pub mod database;
|
||||
/// Database metrics trait extensions.
|
||||
pub mod database_metrics;
|
||||
/// mock
|
||||
pub mod mock;
|
||||
/// Table traits
|
||||
|
||||
@@ -2,14 +2,18 @@
|
||||
|
||||
use crate::{
|
||||
database::Database,
|
||||
database_metrics::DatabaseMetrics,
|
||||
tables::{TableType, Tables},
|
||||
utils::default_page_size,
|
||||
DatabaseError,
|
||||
};
|
||||
use eyre::Context;
|
||||
use metrics::gauge;
|
||||
use reth_interfaces::db::LogLevel;
|
||||
use reth_libmdbx::{
|
||||
DatabaseFlags, Environment, EnvironmentFlags, Geometry, Mode, PageSize, SyncMode, RO, RW,
|
||||
};
|
||||
use reth_tracing::tracing::error;
|
||||
use std::{ops::Deref, path::Path};
|
||||
use tx::Tx;
|
||||
|
||||
@@ -59,6 +63,44 @@ impl Database for DatabaseEnv {
|
||||
}
|
||||
}
|
||||
|
||||
impl DatabaseMetrics for DatabaseEnv {
|
||||
fn report_metrics(&self) {
|
||||
let _ = self.view(|tx| {
|
||||
for table in Tables::ALL.iter().map(|table| table.name()) {
|
||||
let table_db =
|
||||
tx.inner.open_db(Some(table)).wrap_err("Could not open db.")?;
|
||||
|
||||
let stats = tx
|
||||
.inner
|
||||
.db_stat(&table_db)
|
||||
.wrap_err(format!("Could not find table: {table}"))?;
|
||||
|
||||
let page_size = stats.page_size() as usize;
|
||||
let leaf_pages = stats.leaf_pages();
|
||||
let branch_pages = stats.branch_pages();
|
||||
let overflow_pages = stats.overflow_pages();
|
||||
let num_pages = leaf_pages + branch_pages + overflow_pages;
|
||||
let table_size = page_size * num_pages;
|
||||
let entries = stats.entries();
|
||||
|
||||
gauge!("db.table_size", table_size as f64, "table" => table);
|
||||
gauge!("db.table_pages", leaf_pages as f64, "table" => table, "type" => "leaf");
|
||||
gauge!("db.table_pages", branch_pages as f64, "table" => table, "type" => "branch");
|
||||
gauge!("db.table_pages", overflow_pages as f64, "table" => table, "type" => "overflow");
|
||||
gauge!("db.table_entries", entries as f64, "table" => table);
|
||||
}
|
||||
|
||||
Ok::<(), eyre::Report>(())
|
||||
}).map_err(|error| error!(?error, "Failed to read db table stats"));
|
||||
|
||||
if let Ok(freelist) =
|
||||
self.freelist().map_err(|error| error!(?error, "Failed to read db.freelist"))
|
||||
{
|
||||
gauge!("db.freelist", freelist as f64);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl DatabaseEnv {
|
||||
/// Opens the database at the specified path with the given `EnvKind`.
|
||||
///
|
||||
|
||||
@@ -153,7 +153,7 @@ pub fn open_db(path: &Path, log_level: Option<LogLevel>) -> eyre::Result<Databas
|
||||
#[cfg(any(test, feature = "test-utils"))]
|
||||
pub mod test_utils {
|
||||
use super::*;
|
||||
use crate::database::Database;
|
||||
use crate::{database::Database, database_metrics::DatabaseMetrics};
|
||||
use std::{path::PathBuf, sync::Arc};
|
||||
|
||||
/// Error during database open
|
||||
@@ -210,6 +210,12 @@ pub mod test_utils {
|
||||
}
|
||||
}
|
||||
|
||||
impl<DB: DatabaseMetrics> DatabaseMetrics for TempDatabase<DB> {
|
||||
fn report_metrics(&self) {
|
||||
self.db().report_metrics()
|
||||
}
|
||||
}
|
||||
|
||||
/// Create read/write database for testing
|
||||
pub fn create_test_rw_db() -> Arc<TempDatabase<DatabaseEnv>> {
|
||||
let path = tempfile::TempDir::new().expect(ERROR_TEMPDIR).into_path();
|
||||
|
||||
Reference in New Issue
Block a user