diff --git a/Taskfile.yml b/Taskfile.yml index 4b347993f6a3..f669240dcd4c 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -205,6 +205,7 @@ tasks: BENCHMARK_OUTPUT_FILE: '{{.BENCHMARK_OUTPUT_FILE | default ""}}' METRICS_SERVER_ENABLED: '{{.METRICS_SERVER_ENABLED | default "false"}}' METRICS_COLLECTOR_ENABLED: '{{.METRICS_COLLECTOR_ENABLED | default "false"}}' + METRICS_SERVER_PORT: '{{.METRICS_SERVER_PORT}}' cmd: | CURRENT_STATE_DIR={{.CURRENT_STATE_DIR}} \ BLOCK_DIR={{.BLOCK_DIR}} \ @@ -216,6 +217,7 @@ tasks: BENCHMARK_OUTPUT_FILE={{.BENCHMARK_OUTPUT_FILE}} \ METRICS_SERVER_ENABLED={{.METRICS_SERVER_ENABLED}} \ METRICS_COLLECTOR_ENABLED={{.METRICS_COLLECTOR_ENABLED}} \ + METRICS_SERVER_PORT={{.METRICS_SERVER_PORT}} \ bash -x ./scripts/benchmark_cchain_range.sh reexecute-cchain-range-with-copied-data: @@ -232,6 +234,7 @@ tasks: BENCHMARK_OUTPUT_FILE: '{{.BENCHMARK_OUTPUT_FILE | default ""}}' METRICS_SERVER_ENABLED: '{{.METRICS_SERVER_ENABLED | default "false"}}' METRICS_COLLECTOR_ENABLED: '{{.METRICS_COLLECTOR_ENABLED | default "false"}}' + METRICS_SERVER_PORT: '{{.METRICS_SERVER_PORT}}' cmds: - task: import-cchain-reexecute-range vars: @@ -250,6 +253,7 @@ tasks: BENCHMARK_OUTPUT_FILE: '{{.BENCHMARK_OUTPUT_FILE}}' METRICS_SERVER_ENABLED: '{{.METRICS_SERVER_ENABLED}}' METRICS_COLLECTOR_ENABLED: '{{.METRICS_COLLECTOR_ENABLED}}' + METRICS_SERVER_PORT: '{{.METRICS_SERVER_PORT}}' test-bootstrap-monitor-e2e: desc: Runs bootstrap monitor e2e tests diff --git a/scripts/benchmark_cchain_range.sh b/scripts/benchmark_cchain_range.sh index 092d02bfe7d6..481197216dff 100755 --- a/scripts/benchmark_cchain_range.sh +++ b/scripts/benchmark_cchain_range.sh @@ -12,6 +12,7 @@ set -euo pipefail # BENCHMARK_OUTPUT_FILE (optional): If set, benchmark output is also written to this file. # METRICS_SERVER_ENABLED (optional): If set, enables the metrics server. # METRICS_COLLECTOR_ENABLED (optional): If set, enables the metrics collector. +# METRICS_SERVER_PORT (optional): If set, determines the port the metrics server will listen to. : "${BLOCK_DIR:?BLOCK_DIR must be set}" : "${CURRENT_STATE_DIR:?CURRENT_STATE_DIR must be set}" @@ -28,7 +29,8 @@ cmd="go test -timeout=0 -v -benchtime=1x -bench=BenchmarkReexecuteRange -run=^$ --end-block=\"${END_BLOCK}\" \ ${LABELS:+--labels=\"${LABELS}\"} \ ${METRICS_SERVER_ENABLED:+--metrics-server-enabled=\"${METRICS_SERVER_ENABLED}\"} \ - ${METRICS_COLLECTOR_ENABLED:+--metrics-collector-enabled=\"${METRICS_COLLECTOR_ENABLED}\"}" + ${METRICS_COLLECTOR_ENABLED:+--metrics-collector-enabled=\"${METRICS_COLLECTOR_ENABLED}\"} \ + ${METRICS_SERVER_PORT:+--metrics-server-port=\"${METRICS_SERVER_PORT}\"}" if [ -n "${BENCHMARK_OUTPUT_FILE:-}" ]; then eval "$cmd" | tee "${BENCHMARK_OUTPUT_FILE}" diff --git a/tests/prometheus_server.go b/tests/prometheus_server.go index c87a61e7fc98..3b48226f0ac7 100644 --- a/tests/prometheus_server.go +++ b/tests/prometheus_server.go @@ -6,6 +6,7 @@ package tests import ( "context" "errors" + "fmt" "net" "net/http" "time" @@ -14,7 +15,10 @@ import ( "github.com/prometheus/client_golang/prometheus/promhttp" ) -const defaultPrometheusListenAddr = "127.0.0.1:0" +const ( + localhostAddr = "127.0.0.1" + defaultMetricsPort = 0 +) // PrometheusServer is a HTTP server that serves Prometheus metrics from the provided // gahterer. @@ -28,25 +32,32 @@ type PrometheusServer struct { // NewPrometheusServer creates and starts a Prometheus server with the provided gatherer // listening on 127.0.0.1:0 and serving /ext/metrics. func NewPrometheusServer(gatherer prometheus.Gatherer) (*PrometheusServer, error) { + return NewPrometheusServerWithPort(gatherer, defaultMetricsPort) +} + +// NewPrometheusServer creates and starts a Prometheus server with the provided gatherer +// listening on 127.0.0.1:port and serving /ext/metrics. +func NewPrometheusServerWithPort(gatherer prometheus.Gatherer, port uint64) (*PrometheusServer, error) { server := &PrometheusServer{ gatherer: gatherer, } - if err := server.start(); err != nil { + serverAddress := fmt.Sprintf("%s:%d", localhostAddr, port) + if err := server.start(serverAddress); err != nil { return nil, err } return server, nil } -// start the Prometheus server on a dynamic port. -func (s *PrometheusServer) start() error { +// start the Prometheus server on address. +func (s *PrometheusServer) start(address string) error { mux := http.NewServeMux() mux.Handle("/ext/metrics", promhttp.HandlerFor(s.gatherer, promhttp.HandlerOpts{})) - listener, err := net.Listen("tcp", defaultPrometheusListenAddr) + listener, err := net.Listen("tcp", address) if err != nil { - return err + return fmt.Errorf("failed to listen on %s: %w", address, err) } s.server = http.Server{ diff --git a/tests/reexecute/c/README.md b/tests/reexecute/c/README.md index 07b01d4d8117..a020165234eb 100644 --- a/tests/reexecute/c/README.md +++ b/tests/reexecute/c/README.md @@ -46,6 +46,7 @@ If running locally, metrics collection can be customized via the following param - `METRICS_SERVER_ENABLED`: starts a Prometheus server exporting VM metrics. - `METRICS_COLLECTOR_ENABLED`: starts a Prometheus collector (if enabled, then `METRICS_SERVER_ENABLED` must be enabled as well). +- `METRICS_SERVER_PORT`: determines the port the metrics server will listen to (set to `0` by default) When utilizing the metrics collector feature, follow the instructions in the e2e [README](../../e2e/README.md#monitoring) to set the required Prometheus environment variables. diff --git a/tests/reexecute/c/vm_reexecute_test.go b/tests/reexecute/c/vm_reexecute_test.go index 44b77458217c..452ecf95bd72 100644 --- a/tests/reexecute/c/vm_reexecute_test.go +++ b/tests/reexecute/c/vm_reexecute_test.go @@ -65,6 +65,7 @@ var ( metricsServerEnabledArg bool metricsCollectorEnabledArg bool + metricsServerPort uint64 networkUUID string = uuid.NewString() labels = map[string]string{ @@ -106,6 +107,7 @@ func TestMain(m *testing.M) { flag.BoolVar(&metricsServerEnabledArg, "metrics-server-enabled", false, "Whether to enable the metrics server.") flag.BoolVar(&metricsCollectorEnabledArg, "metrics-collector-enabled", false, "Whether to enable the metrics collector (if true, then metrics-server-enabled must be true as well).") + flag.Uint64Var(&metricsServerPort, "metrics-server-port", metricsServerPort, "Port which the metrics server will listen to") flag.StringVar(&labelsArg, "labels", "", "Comma separated KV list of metric labels to attach to all exported metrics. Ex. \"owner=tim,runner=snoopy\"") predefinedConfigKeys := slices.Collect(maps.Keys(predefinedConfigs)) @@ -159,6 +161,7 @@ func BenchmarkReexecuteRange(b *testing.B) { chanSizeArg, metricsServerEnabledArg, metricsCollectorEnabledArg, + metricsServerPort, ) }) } @@ -173,6 +176,7 @@ func benchmarkReexecuteRange( chanSize int, metricsServerEnabled bool, metricsCollectorEnabled bool, + metricsPort uint64, ) { r := require.New(b) ctx := context.Background() @@ -192,7 +196,7 @@ func benchmarkReexecuteRange( log := tests.NewDefaultLogger("c-chain-reexecution") if metricsServerEnabled { - serverAddr := startServer(b, log, prefixGatherer) + serverAddr := startServer(b, log, prefixGatherer, metricsPort) if metricsCollectorEnabled { startCollector(b, log, "c-chain-reexecution", labels, serverAddr) @@ -565,10 +569,11 @@ func startServer( tb testing.TB, log logging.Logger, gatherer prometheus.Gatherer, + port uint64, ) string { r := require.New(tb) - server, err := tests.NewPrometheusServer(gatherer) + server, err := tests.NewPrometheusServerWithPort(gatherer, port) r.NoError(err) log.Info("metrics endpoint available",