Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
e096dc1
refactor: block export
RodrigoVillar Dec 2, 2025
fa99ce5
chore: nits
RodrigoVillar Dec 3, 2025
a433a81
chore(reexecute/c): remove go bench from benchmark
RodrigoVillar Dec 2, 2025
c1203b1
chore: remove go bench in workflow
RodrigoVillar Dec 2, 2025
1935adf
chore: reduce diff
RodrigoVillar Dec 2, 2025
b508826
chore: use test context logger
RodrigoVillar Dec 4, 2025
953a76e
chore: clean up benchmarkTool
RodrigoVillar Dec 4, 2025
e6481ab
docs: benchmarking types
RodrigoVillar Dec 4, 2025
89abbde
refactor: use tc wherever convenient
RodrigoVillar Dec 4, 2025
5f55711
refactor: clean up result logging
RodrigoVillar Dec 4, 2025
afac7bc
fix: append unit to base name
RodrigoVillar Dec 4, 2025
a817e73
chore: remove unnecessary log
RodrigoVillar Dec 4, 2025
d0b95de
Merge branch 'master' into rodrigo/custom-benchmarks
RodrigoVillar Dec 9, 2025
828abe3
chore: nit
RodrigoVillar Dec 9, 2025
01f0663
chore: add back require
RodrigoVillar Dec 9, 2025
18b884d
chore: txt => json
RodrigoVillar Dec 9, 2025
d4639ff
docs: remove stale ref
RodrigoVillar Dec 9, 2025
718bc52
docs: nit
RodrigoVillar Dec 9, 2025
b26e8c4
chore: improve logResults()
RodrigoVillar Dec 9, 2025
3588978
chore: address PR review
RodrigoVillar Dec 9, 2025
9e7f54f
Merge branch 'master' into rodrigo/custom-benchmarks
RodrigoVillar Dec 10, 2025
bc78644
chore(reexecute/c): add back scraping of multiple metrics
RodrigoVillar Dec 10, 2025
29da042
Merge branch 'master' into rodrigo/add-back-multiple-metrics
RodrigoVillar Dec 16, 2025
7250778
chore: nit
RodrigoVillar Dec 16, 2025
43f9633
chore: nsPerMs => nanosecondsPerMillisecond
RodrigoVillar Dec 16, 2025
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
106 changes: 106 additions & 0 deletions tests/reexecute/c/metrics.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
// Copyright (C) 2019-2025, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package main

import (
"fmt"
"time"

"github.com/prometheus/client_golang/prometheus"
"github.com/stretchr/testify/require"

"github.com/ava-labs/avalanchego/tests"
)

type metricKind uint

const (
counter metricKind = iota + 1
gauge
)

var (
gasMetric = topLevelMetric{
name: "gas",
query: "avalanche_evm_eth_chain_block_gas_used_processed",
kind: counter,
}
meterVMMetrics = []topLevelMetric{
{
name: "block_parse",
query: "avalanche_meterchainvm_parse_block_sum",
kind: gauge,
},
{
name: "block_verify",
query: "avalanche_meterchainvm_verify_sum",
kind: gauge,
},
{
name: "block_accept",
query: "avalanche_meterchainvm_accept_sum",
kind: gauge,
},
}
)

func getMetricValue(registry prometheus.Gatherer, metric topLevelMetric) (float64, error) {
metricFamilies, err := registry.Gather()
if err != nil {
return 0, fmt.Errorf("failed to gather metrics: %w", err)
}

query := metric.query
for _, mf := range metricFamilies {
switch metric.kind {
case counter:
if mf.GetName() == query {
return mf.GetMetric()[0].Counter.GetValue(), nil
}
case gauge:
if mf.GetName() == query {
return mf.GetMetric()[0].Gauge.GetValue(), nil
}
Comment on lines +58 to +64
Copy link
Collaborator

Choose a reason for hiding this comment

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

Hmm seems that if the kind is mismatched with the actual registered prometheus metric, then it will fail late here.

Is there any way to make this fail earlier / louder / with a better error message if that's the case?

Copy link
Contributor Author

@RodrigoVillar RodrigoVillar Dec 16, 2025

Choose a reason for hiding this comment

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

Not sure what you mean by "it will fail". If we mismatch metric kinds (e.g. say it's a counter but it's actually a gauge), then getMetricValue() will still return, but the value returned will be 0 - I could require that values returned from getMetricValue() are nonzero if that's what you mean for the function to succeed.

default:
return 0, fmt.Errorf("metric type unknown: %d", metric.kind)
}
}

return 0, fmt.Errorf("metric %s not found", query)
}

type topLevelMetric struct {
name string
query string
kind metricKind
}

func getTopLevelMetrics(tc tests.TestContext, tool *benchmarkTool, registry prometheus.Gatherer, elapsed time.Duration) {
r := require.New(tc)

totalGas, err := getMetricValue(registry, gasMetric)
r.NoError(err)
r.NotZero(totalGas, "denominator metric %q has value 0", gasMetric.name)

var (
mgas float64 = 1_000_000
ggas float64 = 1_000_000_000
nanosecondsPerMillisecond float64 = 1_000_000
)

mgasPerSecond := (totalGas / mgas) / elapsed.Seconds()
tool.addResult(mgasPerSecond, "mgas/s")

totalGGas := totalGas / ggas
msPerGGas := (float64(elapsed) / nanosecondsPerMillisecond) / totalGGas
tool.addResult(msPerGGas, "ms/ggas")

for _, metric := range meterVMMetrics {
metricVal, err := getMetricValue(registry, metric)
r.NoError(err)

metricValMS := (metricVal / nanosecondsPerMillisecond) / totalGGas
tool.addResult(metricValMS, metric.name+"_ms/ggas")
}
}
25 changes: 0 additions & 25 deletions tests/reexecute/c/vm_reexecute.go
Original file line number Diff line number Diff line change
Expand Up @@ -654,28 +654,3 @@ func parseCustomLabels(labelsStr string) (map[string]string, error) {
}
return labels, nil
}

func getTopLevelMetrics(tc tests.TestContext, tool *benchmarkTool, registry prometheus.Gatherer, elapsed time.Duration) {
r := require.New(tc)

gasUsed, err := getCounterMetricValue(registry, "avalanche_evm_eth_chain_block_gas_used_processed")
r.NoError(err)
mgasPerSecond := gasUsed / 1_000_000 / elapsed.Seconds()

tool.addResult(mgasPerSecond, "mgas/s")
}

func getCounterMetricValue(registry prometheus.Gatherer, query string) (float64, error) {
metricFamilies, err := registry.Gather()
if err != nil {
return 0, fmt.Errorf("failed to gather metrics: %w", err)
}

for _, mf := range metricFamilies {
if mf.GetName() == query {
return mf.GetMetric()[0].Counter.GetValue(), nil
}
}

return 0, fmt.Errorf("metric %s not found", query)
}