Skip to main content

reth_provider/providers/database/
metrics.rs

1use metrics::{Gauge, Histogram};
2use reth_metrics::Metrics;
3use std::time::{Duration, Instant};
4
5#[derive(Debug)]
6pub(crate) struct DurationsRecorder<'a> {
7    start: Instant,
8    current_metrics: &'a DatabaseProviderMetrics,
9    pub(crate) actions: Vec<(Action, Duration)>,
10    latest: Option<Duration>,
11}
12
13impl<'a> DurationsRecorder<'a> {
14    /// Creates a new durations recorder with the given metrics instance.
15    pub(crate) fn new(metrics: &'a DatabaseProviderMetrics) -> Self {
16        Self { start: Instant::now(), actions: Vec::new(), latest: None, current_metrics: metrics }
17    }
18}
19
20impl<'a> DurationsRecorder<'a> {
21    /// Records the duration since last record, saves it for future logging and instantly reports as
22    /// a metric with `action` label.
23    pub(crate) fn record_relative(&mut self, action: Action) {
24        let elapsed = self.start.elapsed();
25        let duration = elapsed - self.latest.unwrap_or_default();
26
27        self.actions.push((action, duration));
28        self.current_metrics.record_duration(action, duration);
29        self.latest = Some(elapsed);
30    }
31}
32
33#[derive(Debug, Copy, Clone)]
34pub(crate) enum Action {
35    InsertBlock,
36    InsertState,
37    InsertHashes,
38    InsertHistoryIndices,
39    UpdatePipelineStages,
40    InsertHeaderNumbers,
41    InsertBlockBodyIndices,
42    InsertTransactionBlocks,
43    InsertTransactionSenders,
44    InsertTransactionHashNumbers,
45}
46
47/// Database provider metrics
48#[derive(Metrics)]
49#[metrics(scope = "storage.providers.database")]
50pub(crate) struct DatabaseProviderMetrics {
51    /// Duration of insert block
52    insert_block: Histogram,
53    /// Duration of insert state
54    insert_state: Histogram,
55    /// Duration of insert hashes
56    insert_hashes: Histogram,
57    /// Duration of insert history indices
58    insert_history_indices: Histogram,
59    /// Duration of update pipeline stages
60    update_pipeline_stages: Histogram,
61    /// Duration of insert header numbers
62    insert_header_numbers: Histogram,
63    /// Duration of insert block body indices
64    insert_block_body_indices: Histogram,
65    /// Duration of insert transaction blocks
66    insert_tx_blocks: Histogram,
67    /// Duration of insert transaction senders
68    insert_transaction_senders: Histogram,
69    /// Duration of insert transaction hash numbers
70    insert_transaction_hash_numbers: Histogram,
71    /// Duration of `save_blocks`
72    save_blocks_total: Histogram,
73    /// Duration of MDBX work in `save_blocks`
74    save_blocks_mdbx: Histogram,
75    /// Duration of static file work in `save_blocks`
76    save_blocks_sf: Histogram,
77    /// Duration of `RocksDB` work in `save_blocks`
78    save_blocks_rocksdb: Histogram,
79    /// Duration of `insert_block` in `save_blocks`
80    save_blocks_insert_block: Histogram,
81    /// Duration of `write_state` in `save_blocks`
82    save_blocks_write_state: Histogram,
83    /// Duration of `write_hashed_state` in `save_blocks`
84    save_blocks_write_hashed_state: Histogram,
85    /// Duration of `write_trie_updates` in `save_blocks`
86    save_blocks_write_trie_updates: Histogram,
87    /// Duration of `update_history_indices` in `save_blocks`
88    save_blocks_update_history_indices: Histogram,
89    /// Duration of `update_pipeline_stages` in `save_blocks`
90    save_blocks_update_pipeline_stages: Histogram,
91    /// Number of blocks per `save_blocks` call
92    save_blocks_block_count: Histogram,
93    /// Duration of MDBX commit in `save_blocks`
94    save_blocks_commit_mdbx: Histogram,
95    /// Duration of static file commit in `save_blocks`
96    save_blocks_commit_sf: Histogram,
97    /// Duration of `RocksDB` commit in `save_blocks`
98    save_blocks_commit_rocksdb: Histogram,
99    /// Last duration of `save_blocks`
100    save_blocks_total_last: Gauge,
101    /// Last duration of MDBX work in `save_blocks`
102    save_blocks_mdbx_last: Gauge,
103    /// Last duration of static file work in `save_blocks`
104    save_blocks_sf_last: Gauge,
105    /// Last duration of `RocksDB` work in `save_blocks`
106    save_blocks_rocksdb_last: Gauge,
107    /// Last duration of `insert_block` in `save_blocks`
108    save_blocks_insert_block_last: Gauge,
109    /// Last duration of `write_state` in `save_blocks`
110    save_blocks_write_state_last: Gauge,
111    /// Last duration of `write_hashed_state` in `save_blocks`
112    save_blocks_write_hashed_state_last: Gauge,
113    /// Last duration of `write_trie_updates` in `save_blocks`
114    save_blocks_write_trie_updates_last: Gauge,
115    /// Last duration of `update_history_indices` in `save_blocks`
116    save_blocks_update_history_indices_last: Gauge,
117    /// Last duration of `update_pipeline_stages` in `save_blocks`
118    save_blocks_update_pipeline_stages_last: Gauge,
119    /// Last number of blocks per `save_blocks` call
120    save_blocks_block_count_last: Gauge,
121    /// Last duration of MDBX commit in `save_blocks`
122    save_blocks_commit_mdbx_last: Gauge,
123    /// Last duration of static file commit in `save_blocks`
124    save_blocks_commit_sf_last: Gauge,
125    /// Last duration of `RocksDB` commit in `save_blocks`
126    save_blocks_commit_rocksdb_last: Gauge,
127}
128
129/// Timings collected during a `save_blocks` call.
130#[derive(Debug, Default)]
131pub(crate) struct SaveBlocksTimings {
132    pub total: Duration,
133    pub mdbx: Duration,
134    pub sf: Duration,
135    pub rocksdb: Duration,
136    pub insert_block: Duration,
137    pub write_state: Duration,
138    pub write_hashed_state: Duration,
139    pub write_trie_updates: Duration,
140    pub update_history_indices: Duration,
141    pub update_pipeline_stages: Duration,
142    pub block_count: u64,
143}
144
145/// Timings collected during a `commit` call.
146#[derive(Debug, Default)]
147pub(crate) struct CommitTimings {
148    pub mdbx: Duration,
149    pub sf: Duration,
150    pub rocksdb: Duration,
151}
152
153impl DatabaseProviderMetrics {
154    /// Records the duration for the given action.
155    pub(crate) fn record_duration(&self, action: Action, duration: Duration) {
156        match action {
157            Action::InsertBlock => self.insert_block.record(duration),
158            Action::InsertState => self.insert_state.record(duration),
159            Action::InsertHashes => self.insert_hashes.record(duration),
160            Action::InsertHistoryIndices => self.insert_history_indices.record(duration),
161            Action::UpdatePipelineStages => self.update_pipeline_stages.record(duration),
162            Action::InsertHeaderNumbers => self.insert_header_numbers.record(duration),
163            Action::InsertBlockBodyIndices => self.insert_block_body_indices.record(duration),
164            Action::InsertTransactionBlocks => self.insert_tx_blocks.record(duration),
165            Action::InsertTransactionSenders => self.insert_transaction_senders.record(duration),
166            Action::InsertTransactionHashNumbers => {
167                self.insert_transaction_hash_numbers.record(duration)
168            }
169        }
170    }
171
172    /// Records all `save_blocks` timings.
173    pub(crate) fn record_save_blocks(&self, timings: &SaveBlocksTimings) {
174        self.save_blocks_total.record(timings.total);
175        self.save_blocks_mdbx.record(timings.mdbx);
176        self.save_blocks_sf.record(timings.sf);
177        self.save_blocks_rocksdb.record(timings.rocksdb);
178        self.save_blocks_insert_block.record(timings.insert_block);
179        self.save_blocks_write_state.record(timings.write_state);
180        self.save_blocks_write_hashed_state.record(timings.write_hashed_state);
181        self.save_blocks_write_trie_updates.record(timings.write_trie_updates);
182        self.save_blocks_update_history_indices.record(timings.update_history_indices);
183        self.save_blocks_update_pipeline_stages.record(timings.update_pipeline_stages);
184        self.save_blocks_block_count.record(timings.block_count as f64);
185
186        self.save_blocks_total_last.set(timings.total.as_secs_f64());
187        self.save_blocks_mdbx_last.set(timings.mdbx.as_secs_f64());
188        self.save_blocks_sf_last.set(timings.sf.as_secs_f64());
189        self.save_blocks_rocksdb_last.set(timings.rocksdb.as_secs_f64());
190        self.save_blocks_insert_block_last.set(timings.insert_block.as_secs_f64());
191        self.save_blocks_write_state_last.set(timings.write_state.as_secs_f64());
192        self.save_blocks_write_hashed_state_last.set(timings.write_hashed_state.as_secs_f64());
193        self.save_blocks_write_trie_updates_last.set(timings.write_trie_updates.as_secs_f64());
194        self.save_blocks_update_history_indices_last
195            .set(timings.update_history_indices.as_secs_f64());
196        self.save_blocks_update_pipeline_stages_last
197            .set(timings.update_pipeline_stages.as_secs_f64());
198        self.save_blocks_block_count_last.set(timings.block_count as f64);
199    }
200
201    /// Records all commit timings.
202    pub(crate) fn record_commit(&self, timings: &CommitTimings) {
203        self.save_blocks_commit_mdbx.record(timings.mdbx);
204        self.save_blocks_commit_sf.record(timings.sf);
205        self.save_blocks_commit_rocksdb.record(timings.rocksdb);
206
207        self.save_blocks_commit_mdbx_last.set(timings.mdbx.as_secs_f64());
208        self.save_blocks_commit_sf_last.set(timings.sf.as_secs_f64());
209        self.save_blocks_commit_rocksdb_last.set(timings.rocksdb.as_secs_f64());
210    }
211}