From 3606fc1d8f103b4f7174301f9a985ace2b89038d Mon Sep 17 00:00:00 2001 From: Ryan Doyle Date: Fri, 8 Nov 2024 03:36:56 -0700 Subject: [PATCH] feat(vm_executor): Add new histogram metric for gas per tx in vm_executor (#3215) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What ❔ - Adds a new histogram metric representing total gas used per tx - Adds a new histogram metric representing the gas limit per failed tx ## Why ❔ - The existing metric is a histogram of rates. That's a little difficult to extract useful throughput numbers out of with the notable exception of efficiency. - Exporting this metric to let the consumer do their own: rate/anomoly calculation on gas/tx, ratio of gas burn for failed tx, etc. ## Checklist - [x] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [x] Tests for the changes have been added / updated. - [x] Documentation comments have been added / updated. - [x] Code has been formatted via `zkstack dev fmt` and `zkstack dev lint`. --- core/lib/vm_executor/src/batch/executor.rs | 9 ++++++--- core/lib/vm_executor/src/batch/metrics.rs | 10 ++++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/core/lib/vm_executor/src/batch/executor.rs b/core/lib/vm_executor/src/batch/executor.rs index 6dc9354fd7db..12b0718a4a56 100644 --- a/core/lib/vm_executor/src/batch/executor.rs +++ b/core/lib/vm_executor/src/batch/executor.rs @@ -99,11 +99,13 @@ where let elapsed = latency.observe(); if !res.tx_result.result.is_failed() { - let gas_per_nanosecond = - res.tx_result.statistics.computational_gas_used as f64 / elapsed.as_nanos() as f64; + let gas_used = res.tx_result.statistics.computational_gas_used; EXECUTOR_METRICS .computational_gas_per_nanosecond - .observe(gas_per_nanosecond); + .observe(gas_used as f64 / elapsed.as_nanos() as f64); + EXECUTOR_METRICS + .computational_gas_used + .observe(gas_used.into()); } else { // The amount of computational gas paid for failed transactions is hard to get // but comparing to the gas limit makes sense, since we can burn all gas @@ -111,6 +113,7 @@ where EXECUTOR_METRICS .failed_tx_gas_limit_per_nanosecond .observe(tx_gas_limit as f64 / elapsed.as_nanos() as f64); + EXECUTOR_METRICS.failed_tx_gas_limit.observe(tx_gas_limit); } Ok(res) } diff --git a/core/lib/vm_executor/src/batch/metrics.rs b/core/lib/vm_executor/src/batch/metrics.rs index 6851193e9be9..37f7997c31fd 100644 --- a/core/lib/vm_executor/src/batch/metrics.rs +++ b/core/lib/vm_executor/src/batch/metrics.rs @@ -21,6 +21,10 @@ const GAS_PER_NANOSECOND_BUCKETS: Buckets = Buckets::values(&[ 0.01, 0.03, 0.1, 0.3, 0.5, 0.75, 1., 1.5, 3., 5., 10., 20., 50., ]); +const GAS_USED_BUCKETS: Buckets = Buckets::values(&[ + 10000., 25000., 45000., 70000., 100000., 150000., 225000., 350000., 500000., +]); + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, EncodeLabelValue, EncodeLabelSet)] #[metrics(label = "stage", rename_all = "snake_case")] pub(super) enum TxExecutionStage { @@ -37,8 +41,14 @@ pub(super) struct ExecutorMetrics { pub batch_executor_command_response_time: Family>, #[metrics(buckets = GAS_PER_NANOSECOND_BUCKETS)] pub computational_gas_per_nanosecond: Histogram, + /// Computational gas used, per transaction. + #[metrics(buckets = GAS_USED_BUCKETS)] + pub computational_gas_used: Histogram, #[metrics(buckets = GAS_PER_NANOSECOND_BUCKETS)] pub failed_tx_gas_limit_per_nanosecond: Histogram, + /// Gas limit, per failed transaction. + #[metrics(buckets = GAS_USED_BUCKETS)] + pub failed_tx_gas_limit: Histogram, /// Cumulative latency of interacting with the storage when executing a transaction /// in the batch executor. #[metrics(buckets = Buckets::LATENCIES)]