reth_provider/providers/rocksdb/
metrics.rs1use std::{collections::HashMap, time::Duration};
2
3use itertools::Itertools;
4use metrics::{Counter, Histogram};
5use reth_db::Tables;
6use reth_metrics::Metrics;
7use strum::{EnumIter, IntoEnumIterator};
8
9const ROCKSDB_TABLES: &[&str] = &[Tables::TransactionHashNumbers.name()];
10
11#[derive(Debug)]
13pub(crate) struct RocksDBMetrics {
14 operations: HashMap<(&'static str, RocksDBOperation), RocksDBOperationMetrics>,
15}
16
17impl Default for RocksDBMetrics {
18 fn default() -> Self {
19 let mut operations = ROCKSDB_TABLES
20 .iter()
21 .copied()
22 .cartesian_product(RocksDBOperation::iter())
23 .map(|(table, operation)| {
24 (
25 (table, operation),
26 RocksDBOperationMetrics::new_with_labels(&[
27 ("table", table),
28 ("operation", operation.as_str()),
29 ]),
30 )
31 })
32 .collect::<HashMap<_, _>>();
33
34 operations.insert(
36 ("Batch", RocksDBOperation::BatchWrite),
37 RocksDBOperationMetrics::new_with_labels(&[
38 ("table", "Batch"),
39 ("operation", RocksDBOperation::BatchWrite.as_str()),
40 ]),
41 );
42
43 Self { operations }
44 }
45}
46
47impl RocksDBMetrics {
48 pub(crate) fn record_operation(
50 &self,
51 operation: RocksDBOperation,
52 table: &'static str,
53 duration: Duration,
54 ) {
55 let metrics =
56 self.operations.get(&(table, operation)).expect("operation metrics should exist");
57
58 metrics.calls_total.increment(1);
59 metrics.duration_seconds.record(duration.as_secs_f64());
60 }
61}
62
63#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, EnumIter)]
65pub(crate) enum RocksDBOperation {
66 Get,
67 Put,
68 Delete,
69 BatchWrite,
70}
71
72impl RocksDBOperation {
73 const fn as_str(&self) -> &'static str {
74 match self {
75 Self::Get => "get",
76 Self::Put => "put",
77 Self::Delete => "delete",
78 Self::BatchWrite => "batch-write",
79 }
80 }
81}
82
83#[derive(Metrics, Clone)]
85#[metrics(scope = "rocksdb.provider")]
86pub(crate) struct RocksDBOperationMetrics {
87 calls_total: Counter,
89 duration_seconds: Histogram,
91}