Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add more metrics #2310

Merged
merged 62 commits into from
Oct 14, 2024
Merged
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
eb5525c
Add `gas_per_block` metric
rafal-ch Oct 7, 2024
260b745
Add `transactions_per_block` metric
rafal-ch Oct 7, 2024
c84204b
Add `fee_per_block` metric
rafal-ch Oct 7, 2024
8c5a979
Correct bucket names
rafal-ch Oct 7, 2024
ddb424e
Producer metrics - gas price
acerone85 Oct 7, 2024
27fb0fd
Update bucket values for new metrics
rafal-ch Oct 7, 2024
09357db
chore: add libp2p bandwidth metrics
rymnc Oct 7, 2024
088b918
fix: use dns
rymnc Oct 7, 2024
76b1084
chore: more p2p metrics
rymnc Oct 7, 2024
090ada8
Rework histogram bucket initialization
rafal-ch Oct 8, 2024
bd8b64b
Bucket access function returns iterator
rafal-ch Oct 8, 2024
f205434
Extract the `buckets` module
rafal-ch Oct 8, 2024
de98ec5
Update changelog
rafal-ch Oct 8, 2024
58cf08b
Merge remote-tracking branch 'upstream/master' into 807_add_more_metrics
rafal-ch Oct 8, 2024
c897f8a
Fix `tokio` dependencies
rafal-ch Oct 8, 2024
f184a61
Add test for the presence of all required buckets
rafal-ch Oct 8, 2024
b86efce
Additional length assert in bucket tests
rafal-ch Oct 8, 2024
b8241a0
Remove the `GasPrice` metric
rafal-ch Oct 8, 2024
94f3d42
Fix `strum` dependency definition
rafal-ch Oct 8, 2024
4166809
Update the metric bucket values
rafal-ch Oct 8, 2024
3b128b5
Use explicit `_gwei` suffix for "fee_per_block" metric
rafal-ch Oct 8, 2024
8817d1a
Update changelog
rafal-ch Oct 8, 2024
9bc707c
Merge branch 'master' into 807_add_more_metrics
rafal-ch Oct 8, 2024
3badebd
Reformat `Buckets::Timing` for clarity
rafal-ch Oct 8, 2024
aadc59f
Merge remote-tracking branch 'upstream/807_add_more_metrics' into 807…
rafal-ch Oct 8, 2024
87eed6d
Calculate `total_gas_used` and `total_fee` in a single pass over tran…
rafal-ch Oct 8, 2024
fa60c9e
Move metrics to executor
rafal-ch Oct 8, 2024
10e3407
Add the `executor_size_per_block_bytes` metric
rafal-ch Oct 8, 2024
0978160
Remove no longer used metrics from the importer
rafal-ch Oct 8, 2024
3920e74
Remove the no longer needed `total_fee()` function
rafal-ch Oct 8, 2024
703a89d
Update executor metrics after processing all transactions from a block
rafal-ch Oct 8, 2024
b10178e
Fix comment
rafal-ch Oct 8, 2024
b41331b
Update bucket sized for 'Fee' metric
rafal-ch Oct 9, 2024
ef13002
Update bucket sized for 'TransactionsCount' metric
rafal-ch Oct 9, 2024
5387bc9
Update bucket sized for 'SizeUsed' metric
rafal-ch Oct 9, 2024
853100d
Move the execution metrics to importer
rafal-ch Oct 9, 2024
37d4cdc
Block importer respects the `--metrics` command line parameter
rafal-ch Oct 9, 2024
2297804
Merge remote-tracking branch 'upstream/master' into 807_add_more_metrics
rafal-ch Oct 11, 2024
11a6cfe
Merge remote-tracking branch 'upstream/master' into 807_add_more_metrics
rafal-ch Oct 14, 2024
c921a09
Add support for comma separated metric configuration
rafal-ch Oct 14, 2024
0785b2d
Update changelog
rafal-ch Oct 14, 2024
aa751cd
Detailed help message string for `disable-metrics`
rafal-ch Oct 14, 2024
0f85f04
Sort dependencies
rafal-ch Oct 14, 2024
21ebbc9
Make the `disable-metrics` cli arg optional
rafal-ch Oct 14, 2024
523932d
Simplify implementation of `HELP_STRING`
rafal-ch Oct 14, 2024
1b5c428
Add additional tests for metrics config
rafal-ch Oct 14, 2024
2fba5d2
Figure out dependencies to be able to run tests locally
rafal-ch Oct 14, 2024
f23b469
Merge remote-tracking branch 'upstream/master' into 807_add_more_metrics
rafal-ch Oct 14, 2024
e67ae19
Fix compilation issues in `metrics` crate
rafal-ch Oct 14, 2024
c043ed7
Change some metrics from histogram to a gauge
rafal-ch Oct 14, 2024
7d17f99
Add `importer_gas_price_for_block` metric
rafal-ch Oct 14, 2024
e0124b6
Simplify metric config handling
rafal-ch Oct 14, 2024
f12185f
Make metric config tests more robust
rafal-ch Oct 14, 2024
be71c4b
Merge branch 'master' into 807_add_more_metrics
xgreenx Oct 14, 2024
a128622
Metric config creation may now return an error
rafal-ch Oct 14, 2024
395f491
Merge remote-tracking branch 'upstream/807_add_more_metrics' into 807…
rafal-ch Oct 14, 2024
eb3872f
Log metrics config at startup
rafal-ch Oct 14, 2024
bee9c6f
Allow creating metrics config from empty string, it's equal to `all`
rafal-ch Oct 14, 2024
8da222a
Merge remote-tracking branch 'upstream/master' into 807_add_more_metrics
rafal-ch Oct 14, 2024
8c0cccc
Reworked parsing of the command for disabled metrics
xgreenx Oct 14, 2024
aa6120a
Merge branch 'master' into 807_add_more_metrics
xgreenx Oct 14, 2024
5aea57a
Show nice log
xgreenx Oct 14, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]

### Added
- [2310](https://github.com/FuelLabs/fuel-core/pull/2310): New metrics: "The total gas used in a block" (`executor_gas_per_block`), "The size of a block in bytes" (`executor_size_per_block_bytes`), "The total fee (gwei) paid by transactions in a block" (`executor_fee_per_block_gwei`), "The total number of transactions in a block" (`executor_transactions_per_block`), P2P metrics for swarm and protocol.

## [Version 0.38.0]

### Added
Expand Down
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion crates/metrics/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,6 @@ regex = "1"
tracing = { workspace = true }

[dev-dependencies]
tokio = { workspace = true, features = ["macros"] }
strum = { workspace = true }
strum_macros = { workspace = true }
tokio = { workspace = true, features = ["macros", "rt-multi-thread", "time"] }
141 changes: 141 additions & 0 deletions crates/metrics/src/buckets.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
use std::{
collections::HashMap,
sync::OnceLock,
};
#[cfg(test)]
use strum_macros::EnumIter;

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(test, derive(EnumIter))]
pub(crate) enum Buckets {
Timing,
GasUsed,
TransactionsCount,
Fee,
SizeUsed,
}
static BUCKETS: OnceLock<HashMap<Buckets, Vec<f64>>> = OnceLock::new();
pub(crate) fn buckets(b: Buckets) -> impl Iterator<Item = f64> {
BUCKETS.get_or_init(initialize_buckets)[&b].iter().copied()
}

#[rustfmt::skip]
fn initialize_buckets() -> HashMap<Buckets, Vec<f64>> {
xgreenx marked this conversation as resolved.
Show resolved Hide resolved
[
(
Buckets::Timing,
vec![
0.005,
0.010,
0.025,
0.050,
0.100,
0.250,
0.500,
1.000,
2.500,
5.000,
10.000,
],
),
(
// Gas limit is 30_000_000.
Buckets::GasUsed,
vec![
10_000.0,
25_000.0,
50_000.0,
100_000.0,
250_000.0,
500_000.0,
1_000_000.0,
3_000_000.0,
7_500_000.0,
15_000_000.0,
25_000_000.0,
],
),
(
// Transaction count is fixed at 65_535.
Buckets::TransactionsCount,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The low end could also be informative in metrics. 1 is good to know and it's a very state of the chain between 1 and even 2 or 3, so I'd prefer to have 1-5 all there I think. And then probably 200, 400, 800, 1600, 3200 on the high end for now. We can always add more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I updated these buckets so that we are very detailed at low, then we reach your proposed high end around 16th bucket, but then I left a few at the very end for the high values. Commit is here: ef13002

Distribution visualisation:
image

vec![
5.0,
10.0,
25.0,
50.0,
100.0,
1_000.0,
5_000.0,
10_000.0,
20_000.0,
40_000.0,
60_000.0,
],
),
(
// 50 ETH is expected to be the realistic maximum fee for the time being.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably should still specify that this is in Gwei.

Also, I don't know if we should bother having so much granularity up high. When I said 50 ETH in our convo, I was thinking in terms of the Maximum conceiveable fee, well beyond what will happen any time soon.

We should have many, much lower.

For example a single tx from testnet here:

gasCosts:{
    fee:"10",
    gasUsed:"87570"
},

This is during low volume, etc, but it's an idea of what we could be working with, much more likely than even 0.05 ETH.

So perhaps we break it down like: 0, 100, 200, 400, 800, 1_600, etc... It's less aggressive than log_10, and gives us helpful granularity.

The highest for now can just be 52_428_800.0? Are we okay with 20 buckets?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably should still specify that this is in Gwei.

The metric itself is explicit about the unit:

        registry.register(
            "executor_fee_per_block_gwei",
            "The total fee (gwei) paid by transactions in a block",
            fee_per_block.clone(),
        );

I see that we don't use gwei across the fuel-core codebase (except for the fuel-gas-price-algorithm crate), which I think makes "gwei" unit a default for developers.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So perhaps we break it down like: 0, 100, 200, 400, 800, 1_600, etc... It's less aggressive than log_10, and gives us helpful granularity.

The highest for now can just be 52_428_800.0? Are we okay with 20 buckets?

Yes, that's a good observation, thanks. I think we're good with ~20 buckets, we can still re-adjust them once we start observing real-world data.

Updated in b41331b

Buckets::Fee,
vec![
50_000_000.0,
400_000_000.0,
1_350_000_000.0,
3_200_000_000.0,
6_250_000_000.0,
10_800_000_000.0,
17_150_000_000.0,
25_600_000_000.0,
36_450_000_000.0,
50_000_000_000.0,
]
),
(
// Consider blocks up to 256kb in size, one bucket per 16kb.
Buckets::SizeUsed,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think some smaller values are useful here too. Down to 0... or whatever header + mint comes to :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated in 5387bc9

vec![
16.0 * 1024.0,
32.0 * 1024.0,
48.0 * 1024.0,
64.0 * 1024.0,
80.0 * 1024.0,
96.0 * 1024.0,
112.0 * 1024.0,
128.0 * 1024.0,
144.0 * 1024.0,
160.0 * 1024.0,
176.0 * 1024.0,
192.0 * 1024.0,
208.0 * 1024.0,
224.0 * 1024.0,
240.0 * 1024.0,
256.0 * 1024.0,
]
),
]
.into_iter()
.collect()
}

#[cfg(test)]
mod tests {
use strum::IntoEnumIterator;

use crate::buckets::Buckets;

use super::initialize_buckets;

#[test]
fn buckets_are_defined_for_every_variant() {
let actual_buckets = initialize_buckets();
let actual_buckets = actual_buckets.keys().collect::<Vec<_>>();

let required_buckets: Vec<_> = Buckets::iter().collect();

assert_eq!(required_buckets.len(), actual_buckets.len());

let all_buckets_defined = required_buckets
.iter()
.all(|required_bucket| actual_buckets.contains(&required_bucket));

assert!(all_buckets_defined)
}
}
64 changes: 64 additions & 0 deletions crates/metrics/src/executor.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
use crate::{
buckets::{
buckets,
Buckets,
},
global_registry,
};
use prometheus_client::metrics::histogram::Histogram;
use std::sync::OnceLock;

pub struct ExecutorMetrics {
pub gas_per_block: Histogram,
pub fee_per_block: Histogram,
pub transactions_per_block: Histogram,
pub size_per_block_bytes: Histogram,
}

impl Default for ExecutorMetrics {
fn default() -> Self {
let gas_per_block = Histogram::new(buckets(Buckets::GasUsed));
let fee_per_block = Histogram::new(buckets(Buckets::Fee));
let transactions_per_block = Histogram::new(buckets(Buckets::TransactionsCount));
let size_per_block_bytes = Histogram::new(buckets(Buckets::SizeUsed));

let mut registry = global_registry().registry.lock();
registry.register(
"executor_gas_per_block",
"The total gas used in a block",
gas_per_block.clone(),
);

registry.register(
"executor_fee_per_block_gwei",
"The total fee (gwei) paid by transactions in a block",
fee_per_block.clone(),
);

registry.register(
"executor_transactions_per_block",
"The total number of transactions in a block",
transactions_per_block.clone(),
);

registry.register(
"executor_size_per_block_bytes",
"The size of a block in bytes",
transactions_per_block.clone(),
);

Self {
gas_per_block,
fee_per_block,
transactions_per_block,
size_per_block_bytes,
}
}
}

// Setup a global static for accessing importer metrics
static EXECUTOR_METRICS: OnceLock<ExecutorMetrics> = OnceLock::new();

pub fn executor_metrics() -> &'static ExecutorMetrics {
EXECUTOR_METRICS.get_or_init(ExecutorMetrics::default)
}
4 changes: 3 additions & 1 deletion crates/metrics/src/future_tracker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,9 @@ impl<T: Future> Future for FutureTracker<T> {

#[cfg(test)]
mod tests {
use super::*;
use std::time::Duration;

use crate::future_tracker::FutureTracker;

#[tokio::test]
async fn empty_future() {
Expand Down
7 changes: 5 additions & 2 deletions crates/metrics/src/graphql_metrics.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use crate::{
buckets::{
buckets,
Buckets,
},
global_registry,
timing_buckets,
};
use prometheus_client::{
encoding::EncodeLabelSet,
Expand Down Expand Up @@ -28,7 +31,7 @@ impl GraphqlMetrics {
fn new() -> Self {
let tx_count_gauge = Gauge::default();
let requests = Family::<Label, Histogram>::new_with_constructor(|| {
Histogram::new(timing_buckets().iter().cloned())
Histogram::new(buckets(Buckets::Timing))
});
let mut registry = global_registry().registry.lock();
registry.register("graphql_request_duration_seconds", "", requests.clone());
Expand Down
8 changes: 5 additions & 3 deletions crates/metrics/src/importer.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use crate::{
buckets::{
buckets,
Buckets,
},
global_registry,
timing_buckets,
};
use prometheus_client::metrics::{
gauge::Gauge,
Expand All @@ -21,8 +24,7 @@ impl Default for ImporterMetrics {
fn default() -> Self {
let block_height_gauge = Gauge::default();
let latest_block_import_ms = Gauge::default();
let execute_and_commit_duration =
Histogram::new(timing_buckets().iter().cloned());
let execute_and_commit_duration = Histogram::new(buckets(Buckets::Timing));

let mut registry = global_registry().registry.lock();
acerone85 marked this conversation as resolved.
Show resolved Hide resolved
registry.register(
Expand Down
12 changes: 2 additions & 10 deletions crates/metrics/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,16 @@ pub struct GlobalRegistry {
pub registry: parking_lot::Mutex<Registry>,
}

mod buckets;
pub mod core_metrics;
pub mod executor;
pub mod future_tracker;
pub mod graphql_metrics;
pub mod importer;
pub mod p2p_metrics;
pub mod services;
pub mod txpool_metrics;

// recommended bucket defaults for logging response times
static BUCKETS: OnceLock<Vec<f64>> = OnceLock::new();
pub fn timing_buckets() -> &'static Vec<f64> {
BUCKETS.get_or_init(|| {
vec![
0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1.0, 2.5, 5.0, 10.0,
]
})
}

static GLOBAL_REGISTER: OnceLock<GlobalRegistry> = OnceLock::new();

pub fn global_registry() -> &'static GlobalRegistry {
Expand Down
1 change: 1 addition & 0 deletions crates/services/executor/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ description = "Fuel Block Executor"

[dependencies]
anyhow = { workspace = true }
fuel-core-metrics = { workspace = true }
fuel-core-storage = { workspace = true, default-features = false, features = [
"alloc",
] }
Expand Down
14 changes: 14 additions & 0 deletions crates/services/executor/src/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::{
},
refs::ContractRef,
};
use fuel_core_metrics::executor::executor_metrics;
use fuel_core_storage::{
column::Column,
kv_store::KeyValueInspect,
Expand Down Expand Up @@ -441,6 +442,19 @@ where
)?;
debug_assert!(data.found_mint, "Mint transaction is not found");

executor_metrics()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we log these metrics only if config.metrics is enabled?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I put up a draft PR, because I'm not sure about how to approach this correctly. Please see the description of this PR: #2323

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As per the convo, metrics have been moved to the importer and this commit makes the importer respect the --metrics parameter.

.gas_per_block
.observe(data.used_gas as f64);
executor_metrics()
.size_per_block_bytes
.observe(data.used_size as f64);
executor_metrics()
.fee_per_block
.observe(data.coinbase as f64);
executor_metrics()
.transactions_per_block
.observe(data.tx_count as f64);

data.changes = block_storage_tx.into_changes();
Ok((partial_block, data))
}
Expand Down
1 change: 1 addition & 0 deletions crates/services/p2p/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ libp2p = { version = "0.53.2", default-features = false, features = [
"tokio",
"yamux",
"websocket",
"metrics",
] }
libp2p-mplex = "0.41.0"
postcard = { workspace = true, features = ["use-std"] }
Expand Down
Loading
Loading