Skip to content

Commit ee897be

Browse files
committed
Add metrics to the database
1 parent 2a274c7 commit ee897be

File tree

20 files changed

+1214
-163
lines changed

20 files changed

+1214
-163
lines changed

Cargo.lock

Lines changed: 27 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 63 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -3,65 +3,65 @@
33
## !!! NOTE: If you add a nimiq module here, also add it to log/src/lib.rs !!!
44
##
55
members = [
6-
"blockchain",
7-
"blockchain-interface",
8-
"blockchain-proxy",
9-
"bls",
10-
"client",
11-
"collections",
12-
"consensus",
13-
"database",
14-
"database/database-value",
15-
"genesis",
16-
"genesis-builder",
17-
"handel",
18-
"hash",
19-
"hash/hash_derive",
20-
"key-derivation",
21-
"keys",
22-
"lib",
23-
"light-blockchain",
24-
"log",
25-
"macros",
26-
"mempool",
27-
"metrics-server",
28-
"mnemonic",
29-
"network-interface",
30-
"network-libp2p",
31-
"network-mock",
32-
"pow-migration",
33-
"primitives",
34-
"primitives/account",
35-
"primitives/block",
36-
"primitives/mmr",
37-
"primitives/subscription",
38-
"primitives/transaction",
39-
"primitives/trie",
40-
"rpc-client",
41-
"rpc-interface",
42-
"rpc-server",
43-
"serde",
44-
"serde/derive",
45-
"spammer",
46-
"tendermint",
47-
"test-log",
48-
"test-log/proc-macro",
49-
"test-utils",
50-
"time",
51-
"tools",
52-
"transaction-builder",
53-
"utils",
54-
"validator",
55-
"validator-network",
56-
"vrf",
57-
"wallet",
58-
"web-client",
59-
"zkp",
60-
"zkp-circuits",
61-
"zkp-component",
62-
"zkp-component/zkp-test-gen",
63-
"zkp-primitives",
64-
"zkp-primitives/pedersen-generators",
6+
"blockchain",
7+
"blockchain-interface",
8+
"blockchain-proxy",
9+
"bls",
10+
"client",
11+
"collections",
12+
"consensus",
13+
"database",
14+
"database/database-value",
15+
"genesis",
16+
"genesis-builder",
17+
"handel",
18+
"hash",
19+
"hash/hash_derive",
20+
"key-derivation",
21+
"keys",
22+
"lib",
23+
"light-blockchain",
24+
"log",
25+
"macros",
26+
"mempool",
27+
"metrics-server",
28+
"mnemonic",
29+
"network-interface",
30+
"network-libp2p",
31+
"network-mock",
32+
"pow-migration",
33+
"primitives",
34+
"primitives/account",
35+
"primitives/block",
36+
"primitives/mmr",
37+
"primitives/subscription",
38+
"primitives/transaction",
39+
"primitives/trie",
40+
"rpc-client",
41+
"rpc-interface",
42+
"rpc-server",
43+
"serde",
44+
"serde/derive",
45+
"spammer",
46+
"tendermint",
47+
"test-log",
48+
"test-log/proc-macro",
49+
"test-utils",
50+
"time",
51+
"tools",
52+
"transaction-builder",
53+
"utils",
54+
"validator",
55+
"validator-network",
56+
"vrf",
57+
"wallet",
58+
"web-client",
59+
"zkp",
60+
"zkp-circuits",
61+
"zkp-component",
62+
"zkp-component/zkp-test-gen",
63+
"zkp-primitives",
64+
"zkp-primitives/pedersen-generators",
6565
]
6666

6767
resolver = "2"
@@ -107,8 +107,8 @@ lto = "thin"
107107

108108
[profile.release-wasm]
109109
inherits = "release"
110-
lto = "fat" # Same as lto = true
111-
opt-level = "s" # Optimize for size
110+
lto = "fat" # Same as lto = true
111+
opt-level = "s" # Optimize for size
112112
strip = "debuginfo"
113113

114114
[profile.release-with-debug]
@@ -162,8 +162,8 @@ categories = ["cryptography::cryptocurrencies"]
162162
keywords = ["nimiq", "cryptocurrency", "blockchain"]
163163

164164
[workspace.lints]
165-
clippy.assigning_clones = "allow" # false positives: https://github.com/rust-lang/rust-clippy/issues/12709
166-
clippy.empty_docs = "allow" # false positives: https://github.com/rust-lang/rust-clippy/issues/12377
165+
clippy.assigning_clones = "allow" # false positives: https://github.com/rust-lang/rust-clippy/issues/12709
166+
clippy.empty_docs = "allow" # false positives: https://github.com/rust-lang/rust-clippy/issues/12377
167167
clippy.large_enum_variant = "allow"
168168
clippy.too_many_arguments = "allow"
169169
clippy.type_complexity = "allow"

client/src/main.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use std::time::Duration;
22

33
use log::info;
4-
use nimiq::prover::prover_main;
54
pub use nimiq::{
65
client::Client,
76
config::{command_line::CommandLine, config::ClientConfig, config_file::ConfigFile},
@@ -13,6 +12,7 @@ pub use nimiq::{
1312
signal_handling::initialize_signal_handler,
1413
},
1514
};
15+
use nimiq::{extras::metrics_server::install_metrics, prover::prover_main};
1616

1717
async fn main_inner() -> Result<(), Error> {
1818
// Keep for potential future reactivation
@@ -39,7 +39,7 @@ async fn main_inner() -> Result<(), Error> {
3939
// Initialize panic hook.
4040
initialize_panic_reporting();
4141

42-
// Initialize signal handler
42+
// Initialize signal handler.
4343
initialize_signal_handler();
4444

4545
// Early return in case of a proving process.
@@ -63,6 +63,12 @@ async fn main_inner() -> Result<(), Error> {
6363
let metrics_config = config.metrics_server.clone();
6464
let metrics_enabled = metrics_config.is_some();
6565

66+
// Initialize database logging.
67+
let mut metrics_collector = None;
68+
if metrics_enabled {
69+
metrics_collector = Some(install_metrics());
70+
}
71+
6672
// Create client from config.
6773
let mut client: Client = Client::from_config(config).await?;
6874

@@ -128,6 +134,7 @@ async fn main_inner() -> Result<(), Error> {
128134
client.consensus_proxy(),
129135
client.network(),
130136
&nimiq_task_metric,
137+
metrics_collector.unwrap(),
131138
)
132139
}
133140

database/Cargo.toml

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
[package]
22
name = "nimiq-database"
33
version.workspace = true
4-
authors = ["Pascal B <git@paberr.net>", "The Nimiq Core Development Team <info@nimiq.com>"]
4+
authors = [
5+
"Pascal B <git@paberr.net>",
6+
"The Nimiq Core Development Team <info@nimiq.com>",
7+
]
58
license.workspace = true
69
edition.workspace = true
710
description = "A LMDB database wrapper with support for volatile storage"
@@ -21,10 +24,15 @@ workspace = true
2124

2225
[dependencies]
2326
bitflags = "2.5"
24-
libmdbx = "0.5.0"
27+
libmdbx = { git = "https://github.com/paberr/libmdbx-rs" }
2528
log = { workspace = true }
2629
tempfile = "3"
2730
thiserror = "1.0"
31+
metrics = "0.23"
32+
parking_lot = "0.12"
33+
rustc-hash = "1.1"
34+
strum = "0.26"
35+
strum_macros = "0.26"
2836

2937
nimiq-database-value = { workspace = true }
3038

database/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use bitflags::bitflags;
22

33
mod error;
44
pub mod mdbx;
5+
pub(crate) mod metrics;
56
/// Database implementation that can handle volatile and persistent storage.
67
pub mod proxy;
78
/// Abstraction for methods related to the database.

database/src/mdbx/cursor.rs

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
1-
use std::{borrow::Cow, marker::PhantomData};
1+
use std::{borrow::Cow, marker::PhantomData, sync::Arc};
22

33
use libmdbx::{TransactionKind, WriteFlags, RO, RW};
44
use nimiq_database_value::{AsDatabaseBytes, FromDatabaseValue};
55

66
use super::{DbKvPair, IntoIter};
7-
use crate::traits::{ReadCursor, WriteCursor};
7+
use crate::{
8+
metrics::{DatabaseEnvMetrics, Operation},
9+
traits::{ReadCursor, WriteCursor},
10+
};
811

912
/// A cursor for navigating the entries within a table.
1013
/// Wraps the libmdbx cursor so that we only expose our own methods.
1114
pub struct MdbxCursor<'txn, K: TransactionKind> {
1215
cursor: libmdbx::Cursor<'txn, K>,
16+
metrics: Option<Arc<DatabaseEnvMetrics>>,
17+
table_name: String,
1318
}
1419
/// Instantiation of the `MdbxCursor` for read transactions.
1520
pub type MdbxReadCursor<'txn> = MdbxCursor<'txn, RO>;
@@ -20,8 +25,33 @@ impl<'txn, Kind> MdbxCursor<'txn, Kind>
2025
where
2126
Kind: TransactionKind,
2227
{
23-
pub(crate) fn new(cursor: libmdbx::Cursor<'txn, Kind>) -> Self {
24-
MdbxCursor { cursor }
28+
pub(crate) fn new(
29+
table_name: &str,
30+
cursor: libmdbx::Cursor<'txn, Kind>,
31+
metrics: Option<Arc<DatabaseEnvMetrics>>,
32+
) -> Self {
33+
MdbxCursor {
34+
table_name: table_name.to_string(),
35+
cursor,
36+
metrics,
37+
}
38+
}
39+
40+
/// If `self.metrics` is `Some(...)`, record a metric with the provided operation and value
41+
/// size.
42+
///
43+
/// Otherwise, just execute the closure.
44+
fn execute_with_operation_metric<R>(
45+
&mut self,
46+
operation: Operation,
47+
value_size: Option<usize>,
48+
f: impl FnOnce(&mut Self) -> R,
49+
) -> R {
50+
if let Some(metrics) = self.metrics.as_ref().cloned() {
51+
metrics.record_operation(&self.table_name.clone(), operation, value_size, || f(self))
52+
} else {
53+
f(self)
54+
}
2555
}
2656
}
2757

@@ -246,13 +276,17 @@ where
246276
{
247277
fn clone(&self) -> Self {
248278
Self {
279+
table_name: self.table_name.clone(),
249280
cursor: self.cursor.clone(),
281+
metrics: self.metrics.as_ref().cloned(),
250282
}
251283
}
252284
}
253285

254286
impl<'txn> WriteCursor<'txn> for MdbxWriteCursor<'txn> {
255287
fn remove(&mut self) {
256-
self.cursor.del(WriteFlags::empty()).unwrap();
288+
self.execute_with_operation_metric(Operation::CursorDeleteCurrent, None, |cursor| {
289+
cursor.cursor.del(WriteFlags::empty()).unwrap();
290+
});
257291
}
258292
}

0 commit comments

Comments
 (0)