Skip to main content

reth_provider/providers/database/
metrics.rs

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