From 25eadad692eea277ea02fe8ad6ad905acd282d0b Mon Sep 17 00:00:00 2001 From: Rakan Al-Huneiti Date: Mon, 16 Dec 2024 14:27:41 +0300 Subject: [PATCH] Prometheus metrics (#1589) --- Cargo.lock | 270 ++++++- Cargo.toml | 45 +- bin/citrea/Cargo.toml | 3 + bin/citrea/src/main.rs | 28 +- bin/citrea/tests/test_helpers/mod.rs | 1 + crates/batch-prover/Cargo.toml | 3 + crates/batch-prover/src/da_block_handler.rs | 3 + crates/batch-prover/src/lib.rs | 1 + crates/batch-prover/src/metrics.rs | 20 + crates/batch-prover/src/runner.rs | 12 +- crates/bitcoin-da/Cargo.toml | 2 + .../helpers/builders/batch_proof_namespace.rs | 10 +- crates/common/src/config.rs | 84 ++ crates/fullnode/Cargo.toml | 3 + crates/fullnode/src/da_block_handler.rs | 14 + crates/fullnode/src/lib.rs | 1 + crates/fullnode/src/metrics.rs | 22 + crates/fullnode/src/runner.rs | 11 + crates/light-client-prover/Cargo.toml | 6 + .../src/da_block_handler.rs | 4 + crates/light-client-prover/src/lib.rs | 2 + crates/light-client-prover/src/metrics.rs | 16 + crates/risc0/Cargo.toml | 2 + crates/risc0/src/host.rs | 3 + crates/sequencer/Cargo.toml | 3 + crates/sequencer/src/commitment/mod.rs | 13 + crates/sequencer/src/lib.rs | 1 + crates/sequencer/src/mempool.rs | 4 + crates/sequencer/src/metrics.rs | 28 + crates/sequencer/src/rpc.rs | 3 + crates/sequencer/src/runner.rs | 20 +- .../db/sov-db/src/ledger_db/traits.rs | 2 + .../full-node/db/sov-schema-db/Cargo.toml | 9 +- .../db/sov-schema-db/src/iterator.rs | 19 +- .../full-node/db/sov-schema-db/src/lib.rs | 50 +- .../full-node/db/sov-schema-db/src/metrics.rs | 142 +--- .../db/sov-schema-db/src/schema_batch.rs | 13 +- docker/docker-compose.telemetry.yaml | 37 + docker/telemetry/prometheus.yml | 22 + resources/grafana/batch-prover.dashboard.json | 469 +++++++++++ resources/grafana/fullnode.dashboard.json | 374 +++++++++ resources/grafana/light-client.dashboard.json | 113 +++ resources/grafana/sequencer.dashboard.json | 729 ++++++++++++++++++ 43 files changed, 2423 insertions(+), 194 deletions(-) create mode 100644 crates/batch-prover/src/metrics.rs create mode 100644 crates/fullnode/src/metrics.rs create mode 100644 crates/light-client-prover/src/metrics.rs create mode 100644 crates/sequencer/src/metrics.rs create mode 100644 docker/docker-compose.telemetry.yaml create mode 100644 docker/telemetry/prometheus.yml create mode 100644 resources/grafana/batch-prover.dashboard.json create mode 100644 resources/grafana/fullnode.dashboard.json create mode 100644 resources/grafana/light-client.dashboard.json create mode 100644 resources/grafana/sequencer.dashboard.json diff --git a/Cargo.lock b/Cargo.lock index ba276ac1c..259ade3d7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1052,6 +1052,32 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +[[package]] +name = "aws-lc-rs" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f47bb8cc16b669d267eeccf585aea077d0882f4777b1c1f740217885d6e6e5a3" +dependencies = [ + "aws-lc-sys", + "paste", + "zeroize", +] + +[[package]] +name = "aws-lc-sys" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2101df3813227bbaaaa0b04cd61c534c7954b22bd68d399b440be937dc63ff7" +dependencies = [ + "bindgen", + "cc", + "cmake", + "dunce", + "fs_extra", + "libc", + "paste", +] + [[package]] name = "backoff" version = "0.4.0" @@ -1167,12 +1193,15 @@ dependencies = [ "itertools 0.12.1", "lazy_static", "lazycell", + "log", + "prettyplease", "proc-macro2", "quote", "regex", "rustc-hash 1.1.0", "shlex", "syn 2.0.87", + "which 4.4.2", ] [[package]] @@ -1232,6 +1261,7 @@ dependencies = [ "hex", "itertools 0.13.0", "jsonrpsee", + "metrics", "pin-project", "rand 0.8.5", "reqwest", @@ -1730,6 +1760,9 @@ dependencies = [ "lazy_static", "log", "log-panics", + "metrics", + "metrics-exporter-prometheus", + "metrics-util", "prover-services", "regex", "reqwest", @@ -1778,7 +1811,10 @@ dependencies = [ "futures", "hex", "jsonrpsee", + "metrics", + "metrics-derive", "num_cpus", + "once_cell", "parking_lot", "prover-services", "rand 0.8.5", @@ -1917,6 +1953,9 @@ dependencies = [ "futures", "hex", "jsonrpsee", + "metrics", + "metrics-derive", + "once_cell", "rand 0.8.5", "reth-primitives", "rs_merkle", @@ -1951,6 +1990,9 @@ dependencies = [ "citrea-primitives", "hex", "jsonrpsee", + "metrics", + "metrics-derive", + "once_cell", "reth-primitives", "sov-db", "sov-ledger-rpc", @@ -2007,6 +2049,7 @@ dependencies = [ "bonsai-sdk", "borsh", "hex", + "metrics", "risc0-zkvm", "serde", "sov-db", @@ -2034,6 +2077,9 @@ dependencies = [ "hex", "hyper", "jsonrpsee", + "metrics", + "metrics-derive", + "once_cell", "parking_lot", "reth-chainspec", "reth-db", @@ -2143,6 +2189,15 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "afb84c814227b90d6895e01398aee0d8033c00e7466aca416fb6a8e0eb19d8a7" +[[package]] +name = "cmake" +version = "0.1.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c682c223677e0e5b6b7f63a64b9351844c3f1b1678a68b7ee617e30fb082620e" +dependencies = [ + "cc", +] + [[package]] name = "colorchoice" version = "1.0.3" @@ -2209,6 +2264,16 @@ dependencies = [ "libc", ] +[[package]] +name = "core-foundation" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b55271e5c8c478ad3f38ad24ef34923091e0548492a266d19b3c0b4d82574c63" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -2222,7 +2287,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" dependencies = [ "bitflags 1.3.2", - "core-foundation", + "core-foundation 0.9.4", "libc", ] @@ -2744,6 +2809,12 @@ dependencies = [ "zeroize", ] +[[package]] +name = "endian-type" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" + [[package]] name = "enr" version = "0.12.1" @@ -2990,6 +3061,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + [[package]] name = "funty" version = "2.0.0" @@ -3472,6 +3549,7 @@ dependencies = [ "hyper-util", "log", "rustls", + "rustls-native-certs 0.8.1", "rustls-pki-types", "tokio", "tokio-rustls", @@ -4231,7 +4309,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" dependencies = [ "cfg-if", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] @@ -4435,6 +4513,58 @@ dependencies = [ "portable-atomic", ] +[[package]] +name = "metrics-derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3dbdd96ed57d565ec744cba02862d707acf373c5772d152abae6ec5c4e24f6c" +dependencies = [ + "proc-macro2", + "quote", + "regex", + "syn 2.0.87", +] + +[[package]] +name = "metrics-exporter-prometheus" +version = "0.15.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4f0c8427b39666bf970460908b213ec09b3b350f20c0c2eabcbba51704a08e6" +dependencies = [ + "base64 0.22.1", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-util", + "indexmap 2.6.0", + "ipnet", + "metrics", + "metrics-util", + "quanta", + "thiserror", + "tokio", + "tracing", +] + +[[package]] +name = "metrics-util" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4259040465c955f9f2f1a4a8a16dc46726169bca0f88e8fb2dbeced487c3e828" +dependencies = [ + "aho-corasick", + "crossbeam-epoch", + "crossbeam-utils", + "hashbrown 0.14.5", + "indexmap 2.6.0", + "metrics", + "num_cpus", + "ordered-float", + "quanta", + "radix_trie", + "sketches-ddsketch", +] + [[package]] name = "mime" version = "0.3.17" @@ -4521,6 +4651,15 @@ dependencies = [ "rayon", ] +[[package]] +name = "nibble_vec" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" +dependencies = [ + "smallvec", +] + [[package]] name = "nom" version = "7.1.3" @@ -4757,6 +4896,15 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" +[[package]] +name = "ordered-float" +version = "4.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c65ee1f9701bf938026630b455d5315f490640234259037edb259798b3bcf85e" +dependencies = [ + "num-traits", +] + [[package]] name = "overload" version = "0.1.1" @@ -4985,6 +5133,16 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "prettyplease" +version = "0.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" +dependencies = [ + "proc-macro2", + "syn 2.0.87", +] + [[package]] name = "primitive-types" version = "0.12.2" @@ -5038,20 +5196,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "prometheus" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d33c28a30771f7f96db69893f78b857f7450d7e0237e9c8fc6427a81bae7ed1" -dependencies = [ - "cfg-if", - "fnv", - "lazy_static", - "memchr", - "parking_lot", - "thiserror", -] - [[package]] name = "proptest" version = "1.5.0" @@ -5163,6 +5307,21 @@ dependencies = [ "parking_lot", ] +[[package]] +name = "quanta" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5167a477619228a0b284fac2674e3c388cba90631d7b7de620e6f1fcd08da5" +dependencies = [ + "crossbeam-utils", + "libc", + "once_cell", + "raw-cpuid", + "wasi 0.11.0+wasi-snapshot-preview1", + "web-sys", + "winapi", +] + [[package]] name = "quick-error" version = "1.2.3" @@ -5233,6 +5392,16 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" +[[package]] +name = "radix_trie" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd" +dependencies = [ + "endian-type", + "nibble_vec", +] + [[package]] name = "rand" version = "0.7.3" @@ -5313,6 +5482,15 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "raw-cpuid" +version = "11.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ab240315c661615f2ee9f0f2cd32d5a7343a84d5ebcccb99d46e6637565e7b0" +dependencies = [ + "bitflags 2.6.0", +] + [[package]] name = "rawpointer" version = "0.2.1" @@ -6404,7 +6582,7 @@ dependencies = [ "rayon", "sha2", "tempfile", - "which", + "which 6.0.3", ] [[package]] @@ -6799,6 +6977,7 @@ version = "0.23.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c9cc1d47e243d655ace55ed38201c19ae02c148ae56412ab8750e8f0166ab7f" dependencies = [ + "aws-lc-rs", "log", "once_cell", "ring", @@ -6818,7 +6997,19 @@ dependencies = [ "rustls-pemfile", "rustls-pki-types", "schannel", - "security-framework", + "security-framework 2.11.1", +] + +[[package]] +name = "rustls-native-certs" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcff2dd52b58a8d98a70243663a0d234c4e2b79235637849d15913394a247d3" +dependencies = [ + "openssl-probe", + "rustls-pki-types", + "schannel", + "security-framework 3.0.1", ] [[package]] @@ -6842,16 +7033,16 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "afbb878bdfdf63a336a5e63561b1835e7a8c91524f51621db870169eac84b490" dependencies = [ - "core-foundation", + "core-foundation 0.9.4", "core-foundation-sys", "jni", "log", "once_cell", "rustls", - "rustls-native-certs", + "rustls-native-certs 0.7.3", "rustls-platform-verifier-android", "rustls-webpki", - "security-framework", + "security-framework 2.11.1", "security-framework-sys", "webpki-roots", "winapi", @@ -6869,6 +7060,7 @@ version = "0.102.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" dependencies = [ + "aws-lc-rs", "ring", "rustls-pki-types", "untrusted", @@ -7010,13 +7202,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ "bitflags 2.6.0", - "core-foundation", + "core-foundation 0.9.4", "core-foundation-sys", "libc", "num-bigint 0.4.6", "security-framework-sys", ] +[[package]] +name = "security-framework" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1415a607e92bec364ea2cf9264646dcce0f91e6d65281bd6f2819cca3bf39c8" +dependencies = [ + "bitflags 2.6.0", + "core-foundation 0.10.0", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + [[package]] name = "security-framework-sys" version = "2.12.1" @@ -7291,6 +7496,12 @@ dependencies = [ "time", ] +[[package]] +name = "sketches-ddsketch" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85636c14b73d81f541e525f585c0a2109e6744e1565b5c1668e31c70c10ed65c" + [[package]] name = "slab" version = "0.4.9" @@ -7599,8 +7810,9 @@ version = "0.5.0-rc.1" dependencies = [ "anyhow", "byteorder", + "metrics", + "metrics-derive", "once_cell", - "prometheus", "rocksdb", "sov-schema-db", "tempfile", @@ -8617,6 +8829,18 @@ dependencies = [ "rustls-pki-types", ] +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix", +] + [[package]] name = "which" version = "6.0.3" diff --git a/Cargo.toml b/Cargo.toml index 9061ee790..54a8d1c97 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -48,9 +48,6 @@ publish = false repository = "https://github.com/chainwayxyz/citrea" [workspace.dependencies] -# Dependencies maintained by Sovereign -jmt = { git = "https://github.com/penumbra-zone/jmt.git", rev = "fd1c8ef" } - # External dependencies async-trait = "0.1.71" anyhow = { version = "1.0.68", default-features = false } @@ -62,46 +59,55 @@ bincode = "1.3.3" bitcoin = { version = "0.32.2", features = ["serde", "rand"] } bitcoincore-rpc = { version = "0.18.0" } bcs = "0.1.6" +bech32 = { version = "0.9.1", default-features = false } brotli = "7" byteorder = { version = "1.5.0", default-features = false } bytes = { version = "1.2.1", default-features = false } chrono = { version = "0.4.37", default-features = false } +clap = { version = "4.4.10", features = ["derive"] } crypto-bigint = { version = "0.5.5" } digest = { version = "0.10.6", default-features = false, features = ["alloc"] } +derive_more = { version = "0.99.11", default-features = false } +ed25519-dalek = { version = "2", default-features = false, features = ["serde", "fast"] } +futures = "0.3" +hyper = { version = "1.4.0" } itertools = { version = "0.13.0", default-features = false } +jmt = { git = "https://github.com/penumbra-zone/jmt.git", rev = "fd1c8ef" } +jsonrpsee = { version = "0.24.2", features = ["jsonrpsee-types"] } lru = "0.12.3" -rs_merkle = "1.4.2" -futures = "0.3" -pin-project = { version = "1.1.3" } hex = { version = "0.4.3", default-features = false, features = ["alloc", "serde"] } lazy_static = { version = "1.5.0" } log-panics = { version = "2", features = ["with-backtrace"] } once_cell = { version = "1.19.0", default-features = false, features = ["alloc"] } +metrics = { version = "0.23.0" } +metrics-derive = { version = "0.1.0" } +metrics-exporter-prometheus = { version = "0.15.3" } +metrics-util = { version = "0.17.0" } +num_cpus = "1.0" parking_lot = { version = "0.12.3" } -prometheus = { version = "0.13.3", default-features = false } proptest = { version = "1.3.1", default-features = false, features = ["alloc"] } +pin-project = { version = "1.1.3" } rand = "0.8" rayon = "1.8.0" rlimit = "0.10.2" rustc_version_runtime = { version = "0.3.0", default-features = false } +rs_merkle = "1.4.2" reqwest = { version = "0.12.5", features = ["rustls-tls", "json", "http2"], default-features = false } rocksdb = { version = "0.22.0", features = ["lz4"], default-features = false } serde = { version = "1.0.192", default-features = false, features = ["alloc", "derive"] } serde_json = { version = "1.0", default-features = false, features = ["alloc"] } sha2 = { version = "0.10.8", default-features = false } +schemars = { version = "0.8.16", features = ["derive"] } +secp256k1 = { version = "0.29.0", default-features = false, features = ["global-context", "recovery"] } thiserror = "1.0.50" tracing = { version = "0.1.40", default-features = false, features = ["attributes"] } tracing-subscriber = { version = "0.3.17", features = ["env-filter", "json", "fmt"] } -bech32 = { version = "0.9.1", default-features = false } -derive_more = { version = "0.99.11", default-features = false } -clap = { version = "4.4.10", features = ["derive"] } toml = "0.8.0" -jsonrpsee = { version = "0.24.2", features = ["jsonrpsee-types"] } -schemars = { version = "0.8.16", features = ["derive"] } tempfile = "3.8" tokio = { version = "1.40", features = ["full"] } tokio-util = { version = "0.7.12", features = ["rt"] } -num_cpus = "1.0" +tower-http = { version = "0.5.0", features = ["full"] } +tower = { version = "0.4.13", features = ["full"] } # Risc0 dependencies risc0-binfmt = { version = "1.1.3" } @@ -113,6 +119,9 @@ risc0-build = { version = "1.1.3" } bonsai-sdk = { version = "1.1.3" } # EVM dependencies +revm = { version = "12.1", features = ["serde"], default-features = false } +# forcing cargo for this version or else chooses 3.1.1 and there is some dependency conflicts +revm-primitives = { version = "8", default-features = false } revm-inspectors = { version = "=0.5.5", default-features = false } reth-primitives = { git = "https://github.com/paradigmxyz/reth", rev = "a206eb3690e5a51d3c797fed2a6ed722e36863eb", default-features = false } reth-chainspec = { git = "https://github.com/paradigmxyz/reth", rev = "a206eb3690e5a51d3c797fed2a6ed722e36863eb", default-features = false } @@ -131,9 +140,6 @@ reth-trie = { git = "https://github.com/paradigmxyz/reth", rev = "a206eb3690e5a5 reth-rpc = { git = "https://github.com/paradigmxyz/reth", rev = "a206eb3690e5a51d3c797fed2a6ed722e36863eb", default-features = false } reth-stages = { git = "https://github.com/paradigmxyz/reth", rev = "a206eb3690e5a51d3c797fed2a6ed722e36863eb", default-features = false } -revm = { version = "12.1", features = ["serde"], default-features = false } -# forcing cargo for this version or else chooses 3.1.1 and there is some dependency conflicts -revm-primitives = { version = "8", default-features = false } alloy-trie = { version = "0.3.8", default-features = false } alloy-rlp = { version = "0.3.8", default-features = false } alloy-primitives = { version = "0.7.7", default-features = false } @@ -142,13 +148,6 @@ alloy = { version = "0.2.1", default-features = false } alloy-eips = { version = "0.2.1", default-features = false } alloy-consensus = { version = "0.2.1", default-features = false } -ed25519-dalek = { version = "2", default-features = false, features = ["serde", "fast"] } -secp256k1 = { version = "0.29.0", default-features = false, features = ["global-context", "recovery"] } - -tower-http = { version = "0.5.0", features = ["full"] } -tower = { version = "0.4.13", features = ["full"] } -hyper = { version = "1.4.0" } - citrea-e2e = { git = "https://github.com/chainwayxyz/citrea-e2e", rev = "6ba7230" } [patch.crates-io] diff --git a/bin/citrea/Cargo.toml b/bin/citrea/Cargo.toml index de0c37333..391db9caf 100644 --- a/bin/citrea/Cargo.toml +++ b/bin/citrea/Cargo.toml @@ -51,6 +51,9 @@ hex = { workspace = true, optional = true } jsonrpsee = { workspace = true, features = ["http-client", "server"] } lazy_static = { workspace = true } log-panics = { workspace = true } +metrics = { workspace = true } +metrics-exporter-prometheus = { workspace = true, default-features = true } +metrics-util = { workspace = true } reth-primitives = { workspace = true } reth-rpc-types = { workspace = true } reth-transaction-pool = { workspace = true } diff --git a/bin/citrea/src/main.rs b/bin/citrea/src/main.rs index b1f26a7b4..82523fc21 100644 --- a/bin/citrea/src/main.rs +++ b/bin/citrea/src/main.rs @@ -1,6 +1,8 @@ use core::fmt::Debug as DebugTrait; +use std::net::SocketAddr; +use std::time::Duration; -use anyhow::Context as _; +use anyhow::{anyhow, Context as _}; use bitcoin_da::service::BitcoinServiceConfig; use citrea::{ initialize_logging, BitcoinRollup, CitreaRollupBlueprint, MockDemoRollup, NetworkArg, @@ -11,11 +13,13 @@ use citrea_common::{ }; use citrea_stf::genesis_config::GenesisPaths; use clap::Parser; +use metrics_exporter_prometheus::PrometheusBuilder; +use metrics_util::MetricKindMask; use sov_mock_da::MockDaConfig; use sov_modules_api::Spec; use sov_modules_rollup_blueprint::{Network, RollupBlueprint}; use sov_state::storage::NativeStorage; -use tracing::{error, info, instrument}; +use tracing::{debug, error, info, instrument}; #[cfg(test)] mod test_rpc; @@ -201,6 +205,26 @@ where None => FullNodeConfig::from_env() .context("Failed to read rollup configuration from the environment")?, }; + + if rollup_config.telemetry.bind_host.is_some() && rollup_config.telemetry.bind_port.is_some() { + let bind_host = rollup_config.telemetry.bind_host.as_ref().unwrap(); + let bind_port = rollup_config.telemetry.bind_port.as_ref().unwrap(); + let telemetry_addr: SocketAddr = format!("{}:{}", bind_host, bind_port) + .parse() + .map_err(|_| anyhow!("Invalid telemetry address"))?; + + debug!("Starting telemetry server on: {}", telemetry_addr); + + let builder = PrometheusBuilder::new().with_http_listener(telemetry_addr); + builder + .idle_timeout( + MetricKindMask::GAUGE | MetricKindMask::HISTOGRAM, + Some(Duration::from_secs(30)), + ) + .install() + .map_err(|_| anyhow!("failed to install Prometheus recorder"))?; + } + let rollup_blueprint = S::new(network); if let Some(sequencer_config) = sequencer_config { diff --git a/bin/citrea/tests/test_helpers/mod.rs b/bin/citrea/tests/test_helpers/mod.rs index 8f1b51f93..97b451c79 100644 --- a/bin/citrea/tests/test_helpers/mod.rs +++ b/bin/citrea/tests/test_helpers/mod.rs @@ -184,6 +184,7 @@ pub fn create_default_rollup_config( sender_address: MockAddress::from([0; 32]), db_path: da_path.to_path_buf(), }, + telemetry: Default::default(), } } diff --git a/crates/batch-prover/Cargo.toml b/crates/batch-prover/Cargo.toml index 1d7d9d1e9..a5be76779 100644 --- a/crates/batch-prover/Cargo.toml +++ b/crates/batch-prover/Cargo.toml @@ -31,7 +31,10 @@ borsh = { workspace = true } futures = { workspace = true } hex = { workspace = true } jsonrpsee = { workspace = true, features = ["http-client", "server", "client"] } +metrics = { workspace = true } +metrics-derive = { workspace = true } num_cpus = { workspace = true } +once_cell = { workspace = true, default-features = true } parking_lot = { workspace = true } rand = { workspace = true } rayon = { workspace = true } diff --git a/crates/batch-prover/src/da_block_handler.rs b/crates/batch-prover/src/da_block_handler.rs index bdd2f1fed..047e3a8e4 100644 --- a/crates/batch-prover/src/da_block_handler.rs +++ b/crates/batch-prover/src/da_block_handler.rs @@ -33,6 +33,7 @@ use tokio_util::sync::CancellationToken; use tracing::{error, info, warn}; use crate::errors::L1ProcessingError; +use crate::metrics::BATCH_PROVER_METRICS; use crate::proving::{data_to_prove, extract_and_store_proof, prove_l1, GroupCommitments}; type CommitmentStateTransitionData<'txs, Witness, Da, Tx> = ( @@ -270,6 +271,8 @@ where ); } + BATCH_PROVER_METRICS.current_l1_block.set(l1_height as f64); + self.pending_l1_blocks.pop_front(); } Ok(()) diff --git a/crates/batch-prover/src/lib.rs b/crates/batch-prover/src/lib.rs index 1f4c35cc6..a590dcd15 100644 --- a/crates/batch-prover/src/lib.rs +++ b/crates/batch-prover/src/lib.rs @@ -3,6 +3,7 @@ pub mod db_migrations; mod errors; mod runner; pub use runner::*; +mod metrics; mod proving; pub mod rpc; diff --git a/crates/batch-prover/src/metrics.rs b/crates/batch-prover/src/metrics.rs new file mode 100644 index 000000000..9d48e279d --- /dev/null +++ b/crates/batch-prover/src/metrics.rs @@ -0,0 +1,20 @@ +use metrics::{Gauge, Histogram}; +use metrics_derive::Metrics; +use once_cell::sync::Lazy; + +#[derive(Metrics)] +#[metrics(scope = "batch_prover")] +pub struct BatchProverMetrics { + #[metric(describe = "The current L1 block number which is used to produce L2 blocks")] + pub current_l1_block: Gauge, + #[metric(describe = "The current L2 block number")] + pub current_l2_block: Gauge, + #[metric(describe = "The duration of processing a single soft confirmation")] + pub process_soft_confirmation: Histogram, +} + +/// Batch prover metrics +pub static BATCH_PROVER_METRICS: Lazy = Lazy::new(|| { + BatchProverMetrics::describe(); + BatchProverMetrics::default() +}); diff --git a/crates/batch-prover/src/runner.rs b/crates/batch-prover/src/runner.rs index b91e8cd97..fdc965c8b 100644 --- a/crates/batch-prover/src/runner.rs +++ b/crates/batch-prover/src/runner.rs @@ -2,7 +2,7 @@ use core::panic; use std::collections::{HashMap, VecDeque}; use std::net::SocketAddr; use std::sync::Arc; -use std::time::Duration; +use std::time::{Duration, Instant}; use anyhow::{anyhow, bail, Context as _}; use backoff::exponential::ExponentialBackoffBuilder; @@ -38,6 +38,7 @@ use tokio::time::sleep; use tracing::{debug, error, info, instrument}; use crate::da_block_handler::L1BlockHandler; +use crate::metrics::BATCH_PROVER_METRICS; use crate::rpc::{create_rpc_module, RpcContext}; type StfStateRoot = as StateTransitionFunction>::StateRoot; @@ -395,6 +396,8 @@ where l2_height: u64, soft_confirmation: &SoftConfirmationResponse, ) -> anyhow::Result<()> { + let start = Instant::now(); + let current_l1_block = get_da_block_at_height( &self.da_service, soft_confirmation.da_slot_height, @@ -487,6 +490,13 @@ where l2_height, self.state_root ); + BATCH_PROVER_METRICS.current_l2_block.set(l2_height as f64); + BATCH_PROVER_METRICS.process_soft_confirmation.record( + Instant::now() + .saturating_duration_since(start) + .as_secs_f64(), + ); + Ok(()) } diff --git a/crates/bitcoin-da/Cargo.toml b/crates/bitcoin-da/Cargo.toml index 1abb57724..8195ebee3 100644 --- a/crates/bitcoin-da/Cargo.toml +++ b/crates/bitcoin-da/Cargo.toml @@ -26,6 +26,7 @@ crypto-bigint = { workspace = true } hex = { workspace = true, features = ["serde"] } itertools = { workspace = true } jsonrpsee = { workspace = true, optional = true } +metrics = { workspace = true, optional = true } pin-project = { workspace = true, optional = true, features = [] } rand = { workspace = true } reqwest = { workspace = true, optional = true } @@ -49,6 +50,7 @@ native = [ "dep:backoff", "dep:tokio", "dep:tokio-util", + "dep:metrics", "dep:pin-project", "dep:tracing", "sov-rollup-interface/native", diff --git a/crates/bitcoin-da/src/helpers/builders/batch_proof_namespace.rs b/crates/bitcoin-da/src/helpers/builders/batch_proof_namespace.rs index bbc22c236..8ea5902fc 100644 --- a/crates/bitcoin-da/src/helpers/builders/batch_proof_namespace.rs +++ b/crates/bitcoin-da/src/helpers/builders/batch_proof_namespace.rs @@ -2,6 +2,7 @@ use core::result::Result::Ok; use std::fs::File; use std::io::{BufWriter, Write}; use std::path::PathBuf; +use std::time::Instant; use bitcoin::blockdata::opcodes::all::{OP_ENDIF, OP_IF}; use bitcoin::blockdata::opcodes::OP_FALSE; @@ -13,6 +14,7 @@ use bitcoin::opcodes::all::{OP_CHECKSIGVERIFY, OP_NIP}; use bitcoin::script::PushBytesBuf; use bitcoin::secp256k1::{Secp256k1, SecretKey, XOnlyPublicKey}; use bitcoin::{Address, Amount, Network, Transaction}; +use metrics::histogram; use serde::Serialize; use tracing::{instrument, trace, warn}; @@ -119,7 +121,7 @@ pub fn create_batchproof_type_0( .push_slice(PushBytesBuf::try_from(body).expect("Cannot push sequencer commitment")) .push_opcode(OP_ENDIF); - println!("reveal_script_builder: {:?}", reveal_script_builder); + let start = Instant::now(); // Start loop to find a 'nonce' i.e. random number that makes the reveal tx hash starting with zeros given length let mut nonce: i64 = 16; // skip the first digits to avoid OP_PUSHNUM_X loop { @@ -211,6 +213,12 @@ pub fn create_batchproof_type_0( commit_tx_address ); + histogram!("mine_da_transaction").record( + Instant::now() + .saturating_duration_since(start) + .as_secs_f64(), + ); + return Ok(BatchProvingTxs { commit: unsigned_commit_tx, reveal: TxWithId { diff --git a/crates/common/src/config.rs b/crates/common/src/config.rs index 84be06932..cf848f1bc 100644 --- a/crates/common/src/config.rs +++ b/crates/common/src/config.rs @@ -10,6 +10,7 @@ use sov_stf_runner::ProverGuestRunConfig; pub trait FromEnv: Sized { fn from_env() -> anyhow::Result; } + impl FromEnv for PruningConfig { fn from_env() -> anyhow::Result { Ok(PruningConfig { @@ -17,6 +18,7 @@ impl FromEnv for PruningConfig { }) } } + impl FromEnv for sov_mock_da::MockDaConfig { fn from_env() -> anyhow::Result { Ok(Self { @@ -39,6 +41,7 @@ pub struct RunnerConfig { /// Configurations for pruning pub pruning_config: Option, } + impl FromEnv for RunnerConfig { fn from_env() -> anyhow::Result { Ok(Self { @@ -52,6 +55,7 @@ impl FromEnv for RunnerConfig { }) } } + /// RPC configuration. #[derive(Debug, Clone, PartialEq, Deserialize, Default, Serialize)] pub struct RpcConfig { @@ -79,6 +83,7 @@ pub struct RpcConfig { #[serde(default = "default_max_subscriptions_per_connection")] pub max_subscriptions_per_connection: u32, } + impl FromEnv for RpcConfig { fn from_env() -> anyhow::Result { Ok(Self { @@ -112,6 +117,7 @@ impl FromEnv for RpcConfig { }) } } + #[inline] const fn default_max_connections() -> u32 { 100 @@ -155,6 +161,7 @@ pub struct StorageConfig { /// File descriptor limit for RocksDB pub db_max_open_files: Option, } + impl FromEnv for StorageConfig { fn from_env() -> anyhow::Result { Ok(Self { @@ -181,6 +188,7 @@ pub struct RollupPublicKeys { #[serde(with = "hex::serde")] pub prover_da_pub_key: Vec, } + impl FromEnv for RollupPublicKeys { fn from_env() -> anyhow::Result { Ok(Self { @@ -190,6 +198,7 @@ impl FromEnv for RollupPublicKeys { }) } } + /// Rollup Configuration #[derive(Debug, Clone, PartialEq, Deserialize, Serialize)] pub struct FullNodeConfig { @@ -203,7 +212,11 @@ pub struct FullNodeConfig { pub da: BitcoinServiceConfig, /// Important pubkeys pub public_keys: RollupPublicKeys, + /// Telemetry configuration + #[serde(default)] + pub telemetry: TelemetryConfig, } + impl FromEnv for FullNodeConfig { fn from_env() -> anyhow::Result { Ok(Self { @@ -212,9 +225,11 @@ impl FromEnv for FullNodeConfig { runner: RunnerConfig::from_env().ok(), da: DaC::from_env()?, public_keys: RollupPublicKeys::from_env()?, + telemetry: TelemetryConfig::from_env()?, }) } } + /// Prover configuration #[derive(Debug, Clone, PartialEq, Deserialize, Serialize)] pub struct BatchProverConfig { @@ -279,6 +294,7 @@ impl FromEnv for LightClientProverConfig { }) } } + /// Reads toml file as a specific type. pub fn from_toml_path, R: DeserializeOwned>(path: P) -> anyhow::Result { let mut contents = String::new(); @@ -327,6 +343,7 @@ impl Default for SequencerConfig { } } } + impl FromEnv for SequencerConfig { fn from_env() -> anyhow::Result { Ok(Self { @@ -343,6 +360,7 @@ impl FromEnv for SequencerConfig { }) } } + /// Mempool Config for the sequencer /// Read: https://github.com/ledgerwatch/erigon/wiki/Transaction-Pool-Design #[derive(Debug, Clone, PartialEq, Deserialize, Serialize)] @@ -376,6 +394,7 @@ impl Default for SequencerMempoolConfig { } } } + impl FromEnv for SequencerMempoolConfig { fn from_env() -> anyhow::Result { Ok(Self { @@ -389,6 +408,36 @@ impl FromEnv for SequencerMempoolConfig { }) } } + +/// Telemetry configuration. +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)] +pub struct TelemetryConfig { + /// Server host. + pub bind_host: Option, + /// Server port. + pub bind_port: Option, +} + +impl Default for TelemetryConfig { + fn default() -> Self { + Self { + bind_host: Some("0.0.0.0".to_owned()), + bind_port: Some(8081), + } + } +} + +impl FromEnv for TelemetryConfig { + fn from_env() -> anyhow::Result { + let bind_host = std::env::var("TELEMETRY_BIND_HOST").ok(); + let bind_port = std::env::var("TELEMETRY_BIND_PORT").ok(); + Ok(Self { + bind_host, + bind_port: bind_port.map(|p| p.parse()).transpose()?, + }) + } +} + #[cfg(test)] mod tests { use std::io::Write; @@ -430,6 +479,10 @@ mod tests { [runner] include_tx_body = true sequencer_client_url = "http://0.0.0.0:12346" + + [telemetry] + bind_host = "0.0.0.0" + bind_port = 8001 "#.to_owned(); let config_file = create_config_from(&config); @@ -467,6 +520,10 @@ mod tests { sequencer_da_pub_key: vec![119; 32], prover_da_pub_key: vec![], }, + telemetry: TelemetryConfig { + bind_host: Some("0.0.0.0".to_owned()), + bind_port: Some(8001), + }, }; assert_eq!(config, expected); } @@ -621,6 +678,8 @@ mod tests { std::env::set_var("SEQUENCER_CLIENT_URL", "http://0.0.0.0:12346"); std::env::set_var("PRUNING_DISTANCE", "1000"); + std::env::set_var("TELEMETRY_BIND_HOST", "0.0.0.0"); + std::env::set_var("TELEMETRY_BIND_PORT", "8082"); let full_node_config: FullNodeConfig = FullNodeConfig::from_env().unwrap(); @@ -654,7 +713,32 @@ mod tests { sequencer_da_pub_key: vec![119; 32], prover_da_pub_key: vec![], }, + telemetry: TelemetryConfig { + bind_host: Some("0.0.0.0".to_owned()), + bind_port: Some(8082), + }, }; assert_eq!(full_node_config, expected); } + + #[test] + fn test_optional_telemetry_config_from_env() { + let telemetry_config = TelemetryConfig::from_env().unwrap(); + + let expected = TelemetryConfig { + bind_host: None, + bind_port: None, + }; + assert_eq!(telemetry_config, expected); + + std::env::set_var("TELEMETRY_BIND_HOST", "0.0.0.0"); + std::env::set_var("TELEMETRY_BIND_PORT", "5000"); + let telemetry_config = TelemetryConfig::from_env().unwrap(); + + let expected = TelemetryConfig { + bind_host: Some("0.0.0.0".to_owned()), + bind_port: Some(5000), + }; + assert_eq!(telemetry_config, expected); + } } diff --git a/crates/fullnode/Cargo.toml b/crates/fullnode/Cargo.toml index 4bcd728d1..72397abfa 100644 --- a/crates/fullnode/Cargo.toml +++ b/crates/fullnode/Cargo.toml @@ -30,6 +30,9 @@ borsh = { workspace = true } futures = { workspace = true } hex = { workspace = true } jsonrpsee = { workspace = true } +metrics = { workspace = true } +metrics-derive = { workspace = true } +once_cell = { workspace = true, default-features = true } rand = { workspace = true } reth-primitives = { workspace = true } rs_merkle = { workspace = true } diff --git a/crates/fullnode/src/da_block_handler.rs b/crates/fullnode/src/da_block_handler.rs index 34799cfda..02880be85 100644 --- a/crates/fullnode/src/da_block_handler.rs +++ b/crates/fullnode/src/da_block_handler.rs @@ -2,6 +2,7 @@ use std::collections::{HashMap, VecDeque}; use std::fmt::Debug; use std::marker::PhantomData; use std::sync::Arc; +use std::time::Instant; use anyhow::anyhow; use borsh::{BorshDeserialize, BorshSerialize}; @@ -31,6 +32,8 @@ use tokio::time::{sleep, Duration}; use tokio_util::sync::CancellationToken; use tracing::{error, info, warn}; +use crate::metrics::FULLNODE_METRICS; + pub(crate) struct L1BlockHandler where C: Context, @@ -134,6 +137,7 @@ where .front() .expect("Just checked pending L1 blocks is not empty"); let l1_height = l1_block.header().height(); + info!("Processing L1 block at height: {}", l1_height); // Set the l1 height of the l1 hash self.ledger_db @@ -164,6 +168,7 @@ where sequencer_commitments[0].l2_start_block_number, sequencer_commitments[sequencer_commitments.len() - 1].l2_end_block_number, ) { + warn!("L1 commitment received, but L2 range is not synced yet..."); return; } } @@ -209,6 +214,8 @@ where error!("Could not set last scanned l1 height: {}", e); }); + FULLNODE_METRICS.current_l1_block.set(l1_height as f64); + self.pending_l1_blocks.pop_front(); } @@ -428,6 +435,8 @@ async fn sync_l1( let mut l1_height = start_l1_height; info!("Starting to sync from L1 height {}", l1_height); + let start = Instant::now(); + 'block_sync: loop { // TODO: for a node, the da block at slot_height might not have been finalized yet // should wait for it to be finalized @@ -458,6 +467,11 @@ async fn sync_l1( if block_number > l1_height { l1_height = block_number; + FULLNODE_METRICS.scan_l1_block.record( + Instant::now() + .saturating_duration_since(start) + .as_secs_f64(), + ); if let Err(e) = sender.send(l1_block).await { error!("Could not notify about L1 block: {}", e); continue 'block_sync; diff --git a/crates/fullnode/src/lib.rs b/crates/fullnode/src/lib.rs index 834bc790e..28406da97 100644 --- a/crates/fullnode/src/lib.rs +++ b/crates/fullnode/src/lib.rs @@ -2,4 +2,5 @@ pub use runner::*; mod da_block_handler; pub mod db_migrations; +mod metrics; mod runner; diff --git a/crates/fullnode/src/metrics.rs b/crates/fullnode/src/metrics.rs new file mode 100644 index 000000000..992038c68 --- /dev/null +++ b/crates/fullnode/src/metrics.rs @@ -0,0 +1,22 @@ +use metrics::{Gauge, Histogram}; +use metrics_derive::Metrics; +use once_cell::sync::Lazy; + +#[derive(Metrics)] +#[metrics(scope = "fullnode")] +pub struct FullnodeMetrics { + #[metric(describe = "The current L1 block number which is used to produce L2 blocks")] + pub current_l1_block: Gauge, + #[metric(describe = "The current L2 block number")] + pub current_l2_block: Gauge, + #[metric(describe = "The duration of scanning and processing a single L1 block")] + pub scan_l1_block: Histogram, + #[metric(describe = "The duration of processing a single soft confirmation")] + pub process_soft_confirmation: Histogram, +} + +/// Fullnode metrics +pub static FULLNODE_METRICS: Lazy = Lazy::new(|| { + FullnodeMetrics::describe(); + FullnodeMetrics::default() +}); diff --git a/crates/fullnode/src/runner.rs b/crates/fullnode/src/runner.rs index 49460c7df..e41527885 100644 --- a/crates/fullnode/src/runner.rs +++ b/crates/fullnode/src/runner.rs @@ -1,6 +1,7 @@ use std::collections::{HashMap, VecDeque}; use std::net::SocketAddr; use std::sync::Arc; +use std::time::Instant; use anyhow::{bail, Context as _}; use backoff::future::retry as retry_backoff; @@ -37,6 +38,7 @@ use tokio::time::{sleep, Duration}; use tracing::{debug, error, info, instrument}; use crate::da_block_handler::L1BlockHandler; +use crate::metrics::FULLNODE_METRICS; type StateRoot = as StateTransitionFunction>::StateRoot; type StfTransaction = @@ -224,6 +226,8 @@ where l2_height: u64, soft_confirmation: &SoftConfirmationResponse, ) -> anyhow::Result<()> { + let start = Instant::now(); + let current_l1_block = get_da_block_at_height( &self.da_service, soft_confirmation.da_slot_height, @@ -307,6 +311,13 @@ where l2_height, self.state_root ); + FULLNODE_METRICS.current_l2_block.set(l2_height as f64); + FULLNODE_METRICS.process_soft_confirmation.record( + Instant::now() + .saturating_duration_since(start) + .as_secs_f64(), + ); + Ok(()) } diff --git a/crates/light-client-prover/Cargo.toml b/crates/light-client-prover/Cargo.toml index df53c7a23..6eed0af60 100644 --- a/crates/light-client-prover/Cargo.toml +++ b/crates/light-client-prover/Cargo.toml @@ -28,6 +28,9 @@ bincode = { workspace = true } borsh = { workspace = true } hex = { workspace = true } jsonrpsee = { workspace = true, optional = true, features = ["http-client", "server", "client"] } +metrics = { workspace = true, optional = true } +metrics-derive = { workspace = true, optional = true } +once_cell = { workspace = true, default-features = true, optional = true } reth-primitives = { workspace = true, optional = true } tokio = { workspace = true, optional = true } tokio-util = { workspace = true, optional = true } @@ -51,6 +54,9 @@ native = [ "dep:anyhow", "dep:async-trait", "dep:jsonrpsee", + "dep:metrics", + "dep:metrics-derive", + "dep:once_cell", "dep:reth-primitives", "dep:tokio", "dep:tokio-util", diff --git a/crates/light-client-prover/src/da_block_handler.rs b/crates/light-client-prover/src/da_block_handler.rs index a5c06c829..0f6cbf0a1 100644 --- a/crates/light-client-prover/src/da_block_handler.rs +++ b/crates/light-client-prover/src/da_block_handler.rs @@ -27,6 +27,8 @@ use tokio::time::{sleep, Duration}; use tokio_util::sync::CancellationToken; use tracing::{error, info}; +use crate::metrics::LIGHT_CLIENT_METRICS; + pub(crate) struct L1BlockHandler where Da: DaService, @@ -293,6 +295,8 @@ where .set_last_scanned_l1_height(SlotNumber(l1_block.header().height())) .expect("Saving last scanned l1 height to ledger db"); + LIGHT_CLIENT_METRICS.current_l1_block.set(l1_height as f64); + Ok(()) } diff --git a/crates/light-client-prover/src/lib.rs b/crates/light-client-prover/src/lib.rs index fac6e95a2..8b9812818 100644 --- a/crates/light-client-prover/src/lib.rs +++ b/crates/light-client-prover/src/lib.rs @@ -4,6 +4,8 @@ pub mod da_block_handler; #[cfg(feature = "native")] pub mod db_migrations; #[cfg(feature = "native")] +pub mod metrics; +#[cfg(feature = "native")] pub mod rpc; #[cfg(feature = "native")] pub mod runner; diff --git a/crates/light-client-prover/src/metrics.rs b/crates/light-client-prover/src/metrics.rs new file mode 100644 index 000000000..d07673242 --- /dev/null +++ b/crates/light-client-prover/src/metrics.rs @@ -0,0 +1,16 @@ +use metrics::Gauge; +use metrics_derive::Metrics; +use once_cell::sync::Lazy; + +#[derive(Metrics)] +#[metrics(scope = "light_client_prover")] +pub struct LightClientProverMetrics { + #[metric(describe = "The current L1 block number which is used to produce L2 blocks")] + pub current_l1_block: Gauge, +} + +/// Light client metrics +pub static LIGHT_CLIENT_METRICS: Lazy = Lazy::new(|| { + LightClientProverMetrics::describe(); + LightClientProverMetrics::default() +}); diff --git a/crates/risc0/Cargo.toml b/crates/risc0/Cargo.toml index 18c46241c..6e49624d9 100644 --- a/crates/risc0/Cargo.toml +++ b/crates/risc0/Cargo.toml @@ -17,6 +17,7 @@ bincode = { workspace = true } bonsai-sdk = { workspace = true, optional = true } borsh = { workspace = true } hex = { workspace = true } +metrics = { workspace = true, optional = true } risc0-zkvm = { workspace = true, default-features = false, features = ["std"] } serde = { workspace = true } sov-db = { path = "../sovereign-sdk/full-node/db/sov-db", optional = true } @@ -28,6 +29,7 @@ default = [] native = [ "dep:bonsai-sdk", "dep:sov-db", + "dep:metrics", "risc0-zkvm/prove", "sov-rollup-interface/native", ] diff --git a/crates/risc0/src/host.rs b/crates/risc0/src/host.rs index cabe1fd85..32b197caf 100644 --- a/crates/risc0/src/host.rs +++ b/crates/risc0/src/host.rs @@ -1,6 +1,7 @@ //! This module implements the [`ZkvmHost`] trait for the RISC0 VM. use borsh::{BorshDeserialize, BorshSerialize}; +use metrics::histogram; use risc0_zkvm::sha::Digest; use risc0_zkvm::{ compute_image_id, default_prover, AssumptionReceipt, ExecutorEnvBuilder, ProveInfo, ProverOpts, @@ -137,6 +138,8 @@ impl ZkvmHost for Risc0BonsaiHost { let ProveInfo { receipt, stats } = prover.prove_with_opts(env, &elf, &ProverOpts::groth16())?; + histogram!("proving_session_cycle_count").record(stats.total_cycles as f64); + tracing::info!("Execution Stats: {:?}", stats); let image_id = compute_image_id(&elf)?; diff --git a/crates/sequencer/Cargo.toml b/crates/sequencer/Cargo.toml index 7fb66e79a..5e97d6d37 100644 --- a/crates/sequencer/Cargo.toml +++ b/crates/sequencer/Cargo.toml @@ -25,6 +25,9 @@ futures = { workspace = true } hex = { workspace = true } hyper = { workspace = true } jsonrpsee = { workspace = true, features = ["http-client", "server", "client"] } +metrics = { workspace = true } +metrics-derive = { workspace = true } +once_cell = { workspace = true } parking_lot = { workspace = true } rs_merkle = { workspace = true } schnellru = "0.2.1" diff --git a/crates/sequencer/src/commitment/mod.rs b/crates/sequencer/src/commitment/mod.rs index 7b47fd4c2..62622486d 100644 --- a/crates/sequencer/src/commitment/mod.rs +++ b/crates/sequencer/src/commitment/mod.rs @@ -1,5 +1,6 @@ use std::ops::RangeInclusive; use std::sync::Arc; +use std::time::Instant; use anyhow::anyhow; use futures::channel::mpsc::UnboundedReceiver; @@ -18,6 +19,7 @@ use tokio_util::sync::CancellationToken; use tracing::{debug, error, info, instrument}; use self::controller::CommitmentController; +use crate::metrics::SEQUENCER_METRICS; mod controller; @@ -128,6 +130,10 @@ where .map(|sb| sb.hash) .collect::>(); + SEQUENCER_METRICS + .commitment_blocks_count + .set(soft_confirmation_hashes.len() as f64); + let commitment = self.get_commitment(commitment_info, soft_confirmation_hashes)?; debug!("Sequencer: submitting commitment: {:?}", commitment); @@ -145,6 +151,7 @@ where l2_start.0, l2_end.0, ); + let start = Instant::now(); let ledger_db = self.ledger_db.clone(); let handle_da_response = async move { let result: anyhow::Result<()> = async move { @@ -153,6 +160,12 @@ where .map_err(|_| anyhow!("DA service is dead!"))? .map_err(|_| anyhow!("Send transaction cannot fail"))?; + SEQUENCER_METRICS.send_commitment_execution.record( + Instant::now() + .saturating_duration_since(start) + .as_secs_f64(), + ); + ledger_db .set_last_commitment_l2_height(l2_end) .map_err(|_| { diff --git a/crates/sequencer/src/lib.rs b/crates/sequencer/src/lib.rs index 391263e6a..bcf94aca1 100644 --- a/crates/sequencer/src/lib.rs +++ b/crates/sequencer/src/lib.rs @@ -3,6 +3,7 @@ pub mod db_migrations; mod db_provider; mod deposit_data_mempool; mod mempool; +mod metrics; mod rpc; mod runner; mod utils; diff --git a/crates/sequencer/src/mempool.rs b/crates/sequencer/src/mempool.rs index 68903e03c..581bd9dd1 100644 --- a/crates/sequencer/src/mempool.rs +++ b/crates/sequencer/src/mempool.rs @@ -130,4 +130,8 @@ impl CitreaMempool { self.0 .best_transactions_with_attributes(best_transactions_attributes) } + + pub(crate) fn len(&self) -> usize { + self.0.len() + } } diff --git a/crates/sequencer/src/metrics.rs b/crates/sequencer/src/metrics.rs new file mode 100644 index 000000000..398756f0a --- /dev/null +++ b/crates/sequencer/src/metrics.rs @@ -0,0 +1,28 @@ +use metrics::{Gauge, Histogram}; +use metrics_derive::Metrics; +use once_cell::sync::Lazy; + +#[derive(Metrics)] +#[metrics(scope = "sequencer")] +pub struct SequencerMetrics { + #[metric(describe = "How many transactions are currently in the mempool")] + pub mempool_txs: Gauge, + #[metric(describe = "The duration of dry running transactions")] + pub dry_run_execution: Histogram, + #[metric(describe = "The duration of executing block transactions")] + pub block_production_execution: Histogram, + #[metric(describe = "The duration of sending a sequencer commitment")] + pub send_commitment_execution: Histogram, + #[metric(describe = "The number of blocks included in a sequencer commitment")] + pub commitment_blocks_count: Gauge, + #[metric(describe = "The current L2 block number")] + pub current_l2_block: Gauge, + #[metric(describe = "The current L1 block number which is used to produce L2 blocks")] + pub current_l1_block: Gauge, +} + +/// Sequencer metrics +pub static SEQUENCER_METRICS: Lazy = Lazy::new(|| { + SequencerMetrics::describe(); + SequencerMetrics::default() +}); diff --git a/crates/sequencer/src/rpc.rs b/crates/sequencer/src/rpc.rs index 79d74a5fa..283b632a5 100644 --- a/crates/sequencer/src/rpc.rs +++ b/crates/sequencer/src/rpc.rs @@ -17,6 +17,7 @@ use tracing::{debug, error}; use crate::deposit_data_mempool::DepositDataMempool; use crate::mempool::CitreaMempool; +use crate::metrics::SEQUENCER_METRICS; use crate::utils::recover_raw_transaction; pub(crate) struct RpcContext { @@ -97,6 +98,8 @@ impl anyhow::Result<(Vec, Vec)> { + let start = Instant::now(); + let silent_subscriber = tracing_subscriber::registry().with(LevelFilter::OFF); tracing::subscriber::with_default(silent_subscriber, || { @@ -365,6 +368,11 @@ where working_set_to_discard = working_set.checkpoint().to_revertable(); all_txs.push(rlp_tx); } + SEQUENCER_METRICS.dry_run_execution.record( + Instant::now() + .saturating_duration_since(start) + .as_secs_f64(), + ); Ok((all_txs, l1_fee_failed_txs)) } @@ -391,6 +399,7 @@ where l1_fee_rate: u128, l2_block_mode: L2BlockMode, ) -> anyhow::Result<(u64, u64, StateDiff)> { + let start = Instant::now(); let da_height = da_block.header().height(); let (l2_height, l1_height) = match self .ledger_db @@ -590,6 +599,7 @@ where txs_to_remove.extend(l1_fee_failed_txs); self.mempool.remove_transactions(txs_to_remove.clone()); + SEQUENCER_METRICS.mempool_txs.set(self.mempool.len() as f64); let account_updates = self.get_account_updates()?; @@ -603,6 +613,13 @@ where warn!("Failed to remove txs from mempool: {:?}", e); } + SEQUENCER_METRICS.block_production_execution.record( + Instant::now() + .saturating_duration_since(start) + .as_secs_f64(), + ); + SEQUENCER_METRICS.current_l2_block.set(l2_height as f64); + Ok(( l2_height, da_block.header().height(), @@ -709,6 +726,7 @@ where missed_da_blocks_count = self.da_blocks_missed(last_finalized_height, last_used_l1_height); } + SEQUENCER_METRICS.current_l1_block.set(last_finalized_height as f64); }, // If sequencer is in test mode, it will build a block every time it receives a message // The RPC from which the sender can be called is only registered for test mode. This means diff --git a/crates/sovereign-sdk/full-node/db/sov-db/src/ledger_db/traits.rs b/crates/sovereign-sdk/full-node/db/sov-db/src/ledger_db/traits.rs index ad83287f5..befd64c1a 100644 --- a/crates/sovereign-sdk/full-node/db/sov-db/src/ledger_db/traits.rs +++ b/crates/sovereign-sdk/full-node/db/sov-db/src/ledger_db/traits.rs @@ -268,6 +268,8 @@ pub trait SequencerLedgerOps: SharedLedgerOps { /// Test ledger operations #[cfg(test)] pub trait TestLedgerOps { + /// Fetch the test values fn get_values(&self) -> anyhow::Result>; + /// Insert the test values fn put_value(&self, key: u64, value: (u64, u64)) -> anyhow::Result<()>; } diff --git a/crates/sovereign-sdk/full-node/db/sov-schema-db/Cargo.toml b/crates/sovereign-sdk/full-node/db/sov-schema-db/Cargo.toml index e52d1a2f2..6915368fb 100644 --- a/crates/sovereign-sdk/full-node/db/sov-schema-db/Cargo.toml +++ b/crates/sovereign-sdk/full-node/db/sov-schema-db/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "sov-schema-db" +license = "Apache-2.0" # This license is inherited from Aptos description = "A low level interface transforming RocksDB into a type-oriented data store" -license = "Apache-2.0" # This license is inherited from Aptos # Workspace inherited keys version = { workspace = true } @@ -16,17 +16,18 @@ readme = "README.md" # External dependencies anyhow = { workspace = true, default-features = true } byteorder = { workspace = true, default-features = true, optional = true } +metrics = { workspace = true } +metrics-derive = { workspace = true } once_cell = { workspace = true, default-features = true } -prometheus = { workspace = true } rocksdb = { workspace = true } +thiserror = { workspace = true } tokio = { workspace = true } tracing = { workspace = true, default-features = true } -thiserror = { workspace = true } [dev-dependencies] byteorder = { workspace = true, default-features = true } -tempfile = { workspace = true } sov-schema-db = { path = ".", features = ["test-utils"] } +tempfile = { workspace = true } [features] default = [] diff --git a/crates/sovereign-sdk/full-node/db/sov-schema-db/src/iterator.rs b/crates/sovereign-sdk/full-node/db/sov-schema-db/src/iterator.rs index da51a2787..f440c5715 100644 --- a/crates/sovereign-sdk/full-node/db/sov-schema-db/src/iterator.rs +++ b/crates/sovereign-sdk/full-node/db/sov-schema-db/src/iterator.rs @@ -1,9 +1,10 @@ use std::iter::FusedIterator; use std::marker::PhantomData; +use std::time::Instant; use anyhow::Result; +use metrics::histogram; -use crate::metrics::{SCHEMADB_ITER_BYTES, SCHEMADB_ITER_LATENCY_SECONDS}; use crate::schema::{KeyDecoder, Schema, ValueCodec}; use crate::{SchemaKey, SchemaValue}; @@ -96,9 +97,7 @@ where } fn next_impl(&mut self) -> Result>> { - let _timer = SCHEMADB_ITER_LATENCY_SECONDS - .with_label_values(&[S::COLUMN_FAMILY_NAME]) - .start_timer(); + let start = Instant::now(); if !self.db_iter.valid() { self.db_iter.status()?; @@ -108,9 +107,9 @@ where let raw_key = self.db_iter.key().expect("db_iter.key() failed."); let raw_value = self.db_iter.value().expect("db_iter.value() failed."); let value_size_bytes = raw_value.len(); - SCHEMADB_ITER_BYTES - .with_label_values(&[S::COLUMN_FAMILY_NAME]) - .observe((raw_key.len() + raw_value.len()) as f64); + + histogram!("schemadb_iter_bytes", "cf_name" => S::COLUMN_FAMILY_NAME) + .record((raw_key.len() + raw_value.len()) as f64); let key = >::decode_key(raw_key)?; let value = >::decode_value(raw_value)?; @@ -120,6 +119,12 @@ where ScanDirection::Backward => self.db_iter.prev(), } + histogram!("schemadb_iter_latency_seconds", "cf_name" => S::COLUMN_FAMILY_NAME).record( + Instant::now() + .saturating_duration_since(start) + .as_secs_f64(), + ); + Ok(Some(IteratorOutput { key, value, diff --git a/crates/sovereign-sdk/full-node/db/sov-schema-db/src/lib.rs b/crates/sovereign-sdk/full-node/db/sov-schema-db/src/lib.rs index d458f0ddc..136390b3f 100644 --- a/crates/sovereign-sdk/full-node/db/sov-schema-db/src/lib.rs +++ b/crates/sovereign-sdk/full-node/db/sov-schema-db/src/lib.rs @@ -23,20 +23,19 @@ pub mod snapshot; pub mod test; use std::path::Path; +use std::time::Instant; +use ::metrics::{gauge, histogram}; use anyhow::format_err; use iterator::ScanDirection; pub use iterator::{RawDbReverseIterator, SchemaIterator, SeekKeyEncoder}; -use metrics::{ - SCHEMADB_BATCH_COMMIT_BYTES, SCHEMADB_BATCH_COMMIT_LATENCY_SECONDS, SCHEMADB_DELETES, - SCHEMADB_GET_BYTES, SCHEMADB_GET_LATENCY_SECONDS, SCHEMADB_PUT_BYTES, -}; pub use rocksdb; pub use rocksdb::DEFAULT_COLUMN_FAMILY_NAME; use rocksdb::{DBIterator, ReadOptions}; use thiserror::Error; use tracing::info; +pub use crate::metrics::SCHEMADB_METRICS; pub use crate::schema::Schema; use crate::schema::{ColumnFamilyName, KeyCodec, ValueCodec}; pub use crate::schema_batch::{SchemaBatch, SchemaBatchIterator}; @@ -137,22 +136,27 @@ impl DB { } fn _get(&self, schema_key: &impl KeyCodec) -> anyhow::Result> { - let _timer = SCHEMADB_GET_LATENCY_SECONDS - .with_label_values(&[S::COLUMN_FAMILY_NAME]) - .start_timer(); + let start = Instant::now(); let k = schema_key.encode_key()?; let cf_handle = self.get_cf_handle(S::COLUMN_FAMILY_NAME)?; let result = self.inner.get_pinned_cf(cf_handle, k)?; - SCHEMADB_GET_BYTES - .with_label_values(&[S::COLUMN_FAMILY_NAME]) - .observe(result.as_ref().map_or(0.0, |v| v.len() as f64)); - result + histogram!("schemadb_get_bytes", "cf_name" => S::COLUMN_FAMILY_NAME) + .record(result.as_ref().map_or(0.0, |v| v.len() as f64)); + + let result = result .map(|raw_value| >::decode_value(&raw_value)) .transpose() - .map_err(|err| err.into()) + .map_err(|err| err.into()); + + histogram!("schemadb_get_latency_seconds", "cf_name" => S::COLUMN_FAMILY_NAME).record( + Instant::now() + .saturating_duration_since(start) + .as_secs_f64(), + ); + result } /// Writes single record. @@ -282,9 +286,8 @@ impl DB { } fn _write_schemas(&self, batch: SchemaBatch) -> anyhow::Result<()> { - let _timer = SCHEMADB_BATCH_COMMIT_LATENCY_SECONDS - .with_label_values(&[self.name]) - .start_timer(); + let start = Instant::now(); + let mut db_batch = rocksdb::WriteBatch::default(); for (cf_name, rows) in batch.last_writes.iter() { let cf_handle = self.get_cf_handle(cf_name)?; @@ -304,19 +307,22 @@ impl DB { for (key, operation) in rows { match operation { Operation::Put { value } => { - SCHEMADB_PUT_BYTES - .with_label_values(&[cf_name]) - .observe((key.len() + value.len()) as f64); + histogram!("schemadb_put_bytes").record((key.len() + value.len()) as f64); } Operation::Delete => { - SCHEMADB_DELETES.with_label_values(&[cf_name]).inc(); + gauge!("schemadb_deletes", "cf_name" => cf_name.to_owned()).increment(1) } } } } - SCHEMADB_BATCH_COMMIT_BYTES - .with_label_values(&[self.name]) - .observe(serialized_size as f64); + + histogram!("schemadb_batch_commit_bytes").record(serialized_size as f64); + + histogram!("schemadb_batch_commit_latency_seconds", "db_name" => self.name).record( + Instant::now() + .saturating_duration_since(start) + .as_secs_f64(), + ); Ok(()) } diff --git a/crates/sovereign-sdk/full-node/db/sov-schema-db/src/metrics.rs b/crates/sovereign-sdk/full-node/db/sov-schema-db/src/metrics.rs index d0e94dd41..15ccff1ab 100644 --- a/crates/sovereign-sdk/full-node/db/sov-schema-db/src/metrics.rs +++ b/crates/sovereign-sdk/full-node/db/sov-schema-db/src/metrics.rs @@ -1,112 +1,42 @@ // Copyright (c) Aptos // SPDX-License-Identifier: Apache-2.0 +use metrics::{Counter, Histogram}; +use metrics_derive::Metrics; use once_cell::sync::Lazy; -use prometheus::{ - exponential_buckets, register_histogram_vec, register_int_counter_vec, HistogramVec, - IntCounterVec, -}; -pub static SCHEMADB_ITER_LATENCY_SECONDS: Lazy = Lazy::new(|| { - register_histogram_vec!( - // metric name - "schemadb_iter_latency_seconds", - // metric description - "Schemadb iter latency in seconds", - // metric labels (dimensions) - &["cf_name"], - exponential_buckets(/*start=*/ 1e-6, /*factor=*/ 2.0, /*count=*/ 22).unwrap(), - ) - .unwrap() -}); - -pub static SCHEMADB_ITER_BYTES: Lazy = Lazy::new(|| { - register_histogram_vec!( - // metric name - "schemadb_iter_bytes", - // metric description - "Schemadb iter size in bytes", - // metric labels (dimensions) - &["cf_name"] - ) - .unwrap() -}); - -pub static SCHEMADB_GET_LATENCY_SECONDS: Lazy = Lazy::new(|| { - register_histogram_vec!( - // metric name - "schemadb_get_latency_seconds", - // metric description - "Schemadb get latency in seconds", - // metric labels (dimensions) - &["cf_name"], - exponential_buckets(/*start=*/ 1e-6, /*factor=*/ 2.0, /*count=*/ 22).unwrap(), - ) - .unwrap() -}); - -pub static SCHEMADB_GET_BYTES: Lazy = Lazy::new(|| { - register_histogram_vec!( - // metric name - "schemadb_get_bytes", - // metric description - "Schemadb get call returned data size in bytes", - // metric labels (dimensions) - &["cf_name"] - ) - .unwrap() -}); - -pub static SCHEMADB_BATCH_COMMIT_LATENCY_SECONDS: Lazy = Lazy::new(|| { - register_histogram_vec!( - // metric name - "schemadb_batch_commit_latency_seconds", - // metric description - "Schemadb schema batch commit latency in seconds", - // metric labels (dimensions) - &["db_name"], - exponential_buckets(/*start=*/ 1e-3, /*factor=*/ 2.0, /*count=*/ 20).unwrap(), - ) - .unwrap() -}); - -pub static SCHEMADB_BATCH_COMMIT_BYTES: Lazy = Lazy::new(|| { - register_histogram_vec!( - // metric name - "schemadb_batch_commit_bytes", - // metric description - "Schemadb schema batch commit size in bytes", - // metric labels (dimensions) - &["db_name"] - ) - .unwrap() -}); - -pub static SCHEMADB_PUT_BYTES: Lazy = Lazy::new(|| { - register_histogram_vec!( - // metric name - "sov_schema_db_put_bytes", - // metric description - "sov_schema_db put call puts data size in bytes", - // metric labels (dimensions) - &["cf_name"] - ) - .unwrap() -}); - -pub static SCHEMADB_DELETES: Lazy = Lazy::new(|| { - register_int_counter_vec!("storage_deletes", "Storage delete calls", &["cf_name"]).unwrap() -}); - -pub static SCHEMADB_BATCH_PUT_LATENCY_SECONDS: Lazy = Lazy::new(|| { - register_histogram_vec!( - // metric name - "sov_schema_db_batch_put_latency_seconds", - // metric description - "sov_schema_db schema batch put latency in seconds", - // metric labels (dimensions) - &["db_name"], - exponential_buckets(/*start=*/ 1e-3, /*factor=*/ 2.0, /*count=*/ 20).unwrap(), - ) - .unwrap() +/// This defines the struct which encapsulates all metrics used for schema DB. +/// +/// It is unused because we directly use gauge and histogram macros since that is the +/// only way in which we can provide additional labels to the metric. +/// However, deriving `Metrics` here is convenient to provide descriptions for each of +/// the metrics. +#[allow(unused)] +#[derive(Metrics)] +#[metrics(scope = "schemadb")] +pub struct SchemaDbMetrics { + #[metric(describe = "Storage delete calls")] + pub(crate) deletes: Counter, + #[metric(describe = "Schemadb iter latency in seconds")] + pub(crate) iter_latency_seconds: Histogram, + #[metric(describe = "Schemadb iter size in bytes")] + pub(crate) iter_bytes: Histogram, + #[metric(describe = "Schemadb get latency in seconds")] + pub(crate) get_latency_seconds: Histogram, + #[metric(describe = "Schemadb get call returned data size in bytes")] + pub(crate) get_bytes: Histogram, + #[metric(describe = "Schemadb schema batch commit latency in seconds")] + pub(crate) batch_commit_latency_seconds: Histogram, + #[metric(describe = "Schemadb schema batch commit size in bytes")] + pub(crate) batch_commit_bytes: Histogram, + #[metric(describe = "sov_schema_db put call puts data size in bytes")] + pub(crate) batch_put_bytes: Histogram, + #[metric(describe = "sov_schema_db schema batch put latency in seconds")] + pub(crate) batch_put_latency_seconds: Histogram, +} + +/// Schema DB metrics +pub static SCHEMADB_METRICS: Lazy = Lazy::new(|| { + SchemaDbMetrics::describe(); + SchemaDbMetrics::default() }); diff --git a/crates/sovereign-sdk/full-node/db/sov-schema-db/src/schema_batch.rs b/crates/sovereign-sdk/full-node/db/sov-schema-db/src/schema_batch.rs index 46952edfa..0a83d3439 100644 --- a/crates/sovereign-sdk/full-node/db/sov-schema-db/src/schema_batch.rs +++ b/crates/sovereign-sdk/full-node/db/sov-schema-db/src/schema_batch.rs @@ -1,7 +1,9 @@ use std::collections::{btree_map, BTreeMap, HashMap}; use std::iter::Rev; +use std::time::Instant; + +use metrics::histogram; -use crate::metrics::SCHEMADB_BATCH_PUT_LATENCY_SECONDS; use crate::schema::{ColumnFamilyName, KeyCodec, ValueCodec}; use crate::{Operation, Schema, SchemaKey}; @@ -26,14 +28,17 @@ impl SchemaBatch { key: &impl KeyCodec, value: &impl ValueCodec, ) -> anyhow::Result<()> { - let _timer = SCHEMADB_BATCH_PUT_LATENCY_SECONDS - .with_label_values(&["unknown"]) - .start_timer(); + let start = Instant::now(); let key = key.encode_key()?; let put_operation = Operation::Put { value: value.encode_value()?, }; self.insert_operation::(key, put_operation); + histogram!("schemadb_batch_put_latency_seconds").record( + Instant::now() + .saturating_duration_since(start) + .as_secs_f64(), + ); Ok(()) } diff --git a/docker/docker-compose.telemetry.yaml b/docker/docker-compose.telemetry.yaml new file mode 100644 index 000000000..6a36ee934 --- /dev/null +++ b/docker/docker-compose.telemetry.yaml @@ -0,0 +1,37 @@ +services: + prometheus: + image: prom/prometheus + ports: + - 9090:9090 + volumes: + - ./telemetry/prometheus.yml:/etc/prometheus/prometheus.yml + networks: + - monitoring + extra_hosts: + - "host.docker.internal:host-gateway" + + grafana: + image: grafana/grafana-enterprise + ports: + - 3000:3000 + environment: + - GF_SECURITY_ADMIN_PASSWORD=password + networks: + - monitoring + + cadvisor: + image: gcr.io/cadvisor/cadvisor + ports: + - 8080:8080 + volumes: + - /:/rootfs:ro + - /var/run:/var/run:ro + - /sys:/sys:ro + - /var/lib/docker/:/var/lib/docker:ro + - /var/run/docker.sock:/var/run/docker.sock:ro # Add only if you have your containers running on Mac + networks: + - monitoring + +networks: + monitoring: + driver: bridge diff --git a/docker/telemetry/prometheus.yml b/docker/telemetry/prometheus.yml new file mode 100644 index 000000000..f862e6fec --- /dev/null +++ b/docker/telemetry/prometheus.yml @@ -0,0 +1,22 @@ +global: + scrape_interval: 15s + +scrape_configs: + - job_name: 'prometheus' + static_configs: + - targets: ['localhost:9090'] + - job_name: 'cadvisor' + static_configs: + - targets: ['cadvisor:8080'] + - job_name: 'sequencer' + static_configs: + - targets: ['host.docker.internal:8001'] + - job_name: 'fullnode' + static_configs: + - targets: ['host.docker.internal:8002'] + - job_name: 'batch-prover' + static_configs: + - targets: ['host.docker.internal:8003'] + - job_name: 'light-client' + static_configs: + - targets: ['host.docker.internal:8004'] diff --git a/resources/grafana/batch-prover.dashboard.json b/resources/grafana/batch-prover.dashboard.json new file mode 100644 index 000000000..6d536838b --- /dev/null +++ b/resources/grafana/batch-prover.dashboard.json @@ -0,0 +1,469 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": 4, + "links": [], + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "ee6shwrmylmo0b" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 1, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "ee6shwrmylmo0b" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "batch_prover_current_l1_block", + "fullMetaSearch": false, + "includeNullMetadata": true, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Current L1 block", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "ee6shwrmylmo0b" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 0 + }, + "id": 2, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "11.4.0", + "targets": [ + { + "disableTextWrap": false, + "editorMode": "builder", + "expr": "batch_prover_current_l2_block", + "fullMetaSearch": false, + "includeNullMetadata": true, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Current L2 block", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "ee6shwrmylmo0b" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 8 + }, + "id": 3, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "11.4.0", + "targets": [ + { + "disableTextWrap": false, + "editorMode": "builder", + "expr": "batch_prover_process_soft_confirmation", + "fullMetaSearch": false, + "includeNullMetadata": true, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Process soft confirmation", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "ee6shwrmylmo0b" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 8 + }, + "id": 4, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "11.4.0", + "targets": [ + { + "disableTextWrap": false, + "editorMode": "builder", + "expr": "proving_session_cycle_count", + "fullMetaSearch": false, + "includeNullMetadata": true, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Proving session cycle count", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "ee6shwrmylmo0b" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 16 + }, + "id": 5, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "11.4.0", + "targets": [ + { + "disableTextWrap": false, + "editorMode": "builder", + "expr": "mine_da_transaction", + "fullMetaSearch": false, + "includeNullMetadata": true, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Mine DA transaction", + "type": "timeseries" + } + ], + "preload": false, + "schemaVersion": 40, + "tags": [], + "templating": { + "list": [] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": {}, + "timezone": "browser", + "title": "Citrea Batch Prover", + "uid": "ee6vu1k3xzb40b", + "version": 8, + "weekStart": "" +} diff --git a/resources/grafana/fullnode.dashboard.json b/resources/grafana/fullnode.dashboard.json new file mode 100644 index 000000000..eb1b6f9ba --- /dev/null +++ b/resources/grafana/fullnode.dashboard.json @@ -0,0 +1,374 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": 3, + "links": [], + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "ee6shwrmylmo0b" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 1, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "ee6shwrmylmo0b" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "fullnode_current_l1_block", + "fullMetaSearch": false, + "includeNullMetadata": true, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Current L1 block", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "ee6shwrmylmo0b" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 0 + }, + "id": 2, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "11.4.0", + "targets": [ + { + "disableTextWrap": false, + "editorMode": "builder", + "expr": "fullnode_current_l2_block", + "fullMetaSearch": false, + "includeNullMetadata": true, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Current L2 block", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "ee6shwrmylmo0b" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 8 + }, + "id": 3, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "11.4.0", + "targets": [ + { + "disableTextWrap": false, + "editorMode": "builder", + "expr": "fullnode_scan_l1_block", + "fullMetaSearch": false, + "includeNullMetadata": true, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "L1 block scan", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "ee6shwrmylmo0b" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 8 + }, + "id": 4, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "11.4.0", + "targets": [ + { + "disableTextWrap": false, + "editorMode": "builder", + "expr": "fullnode_process_soft_confirmation", + "fullMetaSearch": false, + "includeNullMetadata": true, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Process soft confirmation", + "type": "timeseries" + } + ], + "preload": false, + "refresh": "5s", + "schemaVersion": 40, + "tags": [], + "templating": { + "list": [] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": {}, + "timezone": "browser", + "title": "Citrea Fullnode", + "uid": "fe6skeqv8msxsb", + "version": 6, + "weekStart": "" +} diff --git a/resources/grafana/light-client.dashboard.json b/resources/grafana/light-client.dashboard.json new file mode 100644 index 000000000..00042e53a --- /dev/null +++ b/resources/grafana/light-client.dashboard.json @@ -0,0 +1,113 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": 5, + "links": [], + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "ee6shwrmylmo0b" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 1, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "ee6shwrmylmo0b" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "light_client_prover_current_l1_block", + "fullMetaSearch": false, + "includeNullMetadata": true, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Current L1 block", + "type": "stat" + } + ], + "preload": false, + "schemaVersion": 40, + "tags": [], + "templating": { + "list": [] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": {}, + "timezone": "browser", + "title": "Citrea Light Client", + "uid": "de6vv8uc47cowf", + "version": 3, + "weekStart": "" +} diff --git a/resources/grafana/sequencer.dashboard.json b/resources/grafana/sequencer.dashboard.json new file mode 100644 index 000000000..fdba52384 --- /dev/null +++ b/resources/grafana/sequencer.dashboard.json @@ -0,0 +1,729 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": 2, + "links": [], + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "ee6shwrmylmo0b" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 1, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "11.4.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "ee6shwrmylmo0b" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "sequencer_current_l1_block", + "fullMetaSearch": false, + "includeNullMetadata": true, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Current L1 block", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "ee6shwrmylmo0b" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 0 + }, + "id": 8, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "11.4.0", + "targets": [ + { + "disableTextWrap": false, + "editorMode": "builder", + "expr": "sequencer_current_l2_block", + "fullMetaSearch": false, + "includeNullMetadata": true, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Current L2 block", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "ee6shwrmylmo0b" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 8 + }, + "id": 5, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "11.4.0", + "targets": [ + { + "disableTextWrap": false, + "editorMode": "builder", + "expr": "sequencer_block_production_execution", + "fullMetaSearch": false, + "includeNullMetadata": true, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Produce L2 block", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "ee6shwrmylmo0b" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 8 + }, + "id": 2, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "auto", + "percentChangeColorMode": "standard", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "11.4.0", + "targets": [ + { + "disableTextWrap": false, + "editorMode": "builder", + "expr": "sequencer_mempool_txs", + "fullMetaSearch": false, + "includeNullMetadata": true, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Mempool transactions", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "ee6shwrmylmo0b" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 16 + }, + "id": 4, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "11.4.0", + "targets": [ + { + "disableTextWrap": false, + "editorMode": "builder", + "expr": "sequencer_dry_run_execution", + "fullMetaSearch": false, + "includeNullMetadata": true, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Dry run transactions", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "ee6shwrmylmo0b" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 16 + }, + "id": 3, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "11.4.0", + "targets": [ + { + "disableTextWrap": false, + "editorMode": "builder", + "expr": "rate(sequencer_mempool_txs[$__rate_interval])", + "fullMetaSearch": false, + "includeNullMetadata": true, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Mempool inbound tx/s", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "ee6shwrmylmo0b" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 24 + }, + "id": 6, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "11.4.0", + "targets": [ + { + "disableTextWrap": false, + "editorMode": "builder", + "expr": "sequencer_send_commitment_execution", + "fullMetaSearch": false, + "includeNullMetadata": true, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Commit to L1", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "ee6shwrmylmo0b" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "stepBefore", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 24 + }, + "id": 7, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "11.4.0", + "targets": [ + { + "disableTextWrap": false, + "editorMode": "builder", + "expr": "sequencer_commitment_blocks_count", + "fullMetaSearch": false, + "includeNullMetadata": true, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Commitment blocks count", + "type": "timeseries" + } + ], + "preload": false, + "schemaVersion": 40, + "tags": [], + "templating": { + "list": [] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": {}, + "timezone": "browser", + "title": "Citrea Sequencer", + "uid": "ce6shz4qdkow0f", + "version": 11, + "weekStart": "" +}