diff --git a/Taskfile.yml b/Taskfile.yml index e47de02e0369..fa229d51d012 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -208,6 +208,7 @@ tasks: LABELS: '{{.LABELS | default ""}}' BENCHMARK_OUTPUT_FILE: '{{.BENCHMARK_OUTPUT_FILE | default ""}}' METRICS_SERVER_ENABLED: '{{.METRICS_SERVER_ENABLED | default "false"}}' + METRICS_SERVER_PORT: '{{.METRICS_SERVER_PORT}}' METRICS_COLLECTOR_ENABLED: '{{.METRICS_COLLECTOR_ENABLED | default "false"}}' cmd: | CURRENT_STATE_DIR={{.CURRENT_STATE_DIR}} \ @@ -219,6 +220,7 @@ tasks: LABELS={{.LABELS}} \ BENCHMARK_OUTPUT_FILE={{.BENCHMARK_OUTPUT_FILE}} \ METRICS_SERVER_ENABLED={{.METRICS_SERVER_ENABLED}} \ + METRICS_SERVER_PORT={{.METRICS_SERVER_PORT}} \ METRICS_COLLECTOR_ENABLED={{.METRICS_COLLECTOR_ENABLED}} \ bash -x ./scripts/benchmark_cchain_range.sh @@ -235,6 +237,7 @@ tasks: LABELS: '{{.LABELS | default ""}}' BENCHMARK_OUTPUT_FILE: '{{.BENCHMARK_OUTPUT_FILE | default ""}}' METRICS_SERVER_ENABLED: '{{.METRICS_SERVER_ENABLED | default "false"}}' + METRICS_SERVER_PORT: '{{.METRICS_SERVER_PORT}}' METRICS_COLLECTOR_ENABLED: '{{.METRICS_COLLECTOR_ENABLED | default "false"}}' cmds: - task: import-cchain-reexecute-range @@ -253,6 +256,7 @@ tasks: LABELS: '{{.LABELS}}' BENCHMARK_OUTPUT_FILE: '{{.BENCHMARK_OUTPUT_FILE}}' METRICS_SERVER_ENABLED: '{{.METRICS_SERVER_ENABLED}}' + METRICS_SERVER_PORT: '{{.METRICS_SERVER_PORT}}' METRICS_COLLECTOR_ENABLED: '{{.METRICS_COLLECTOR_ENABLED}}' test-bootstrap-monitor-e2e: diff --git a/scripts/benchmark_cchain_range.sh b/scripts/benchmark_cchain_range.sh index 092d02bfe7d6..0d9d951e7194 100755 --- a/scripts/benchmark_cchain_range.sh +++ b/scripts/benchmark_cchain_range.sh @@ -11,6 +11,7 @@ set -euo pipefail # LABELS (optional): Comma-separated key=value pairs for metric labels. # 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_SERVER_PORT (optional): If set, determines the port the metrics server will listen to. # METRICS_COLLECTOR_ENABLED (optional): If set, enables the metrics collector. : "${BLOCK_DIR:?BLOCK_DIR must be set}" @@ -28,6 +29,7 @@ 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_SERVER_PORT:+--metrics-server-port=\"${METRICS_SERVER_PORT}\"} \ ${METRICS_COLLECTOR_ENABLED:+--metrics-collector-enabled=\"${METRICS_COLLECTOR_ENABLED}\"}" if [ -n "${BENCHMARK_OUTPUT_FILE:-}" ]; then diff --git a/tests/prometheus_server.go b/tests/prometheus_server.go index c87a61e7fc98..07b02c4f4c37 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) +} + +// NewPrometheusServerWithPort 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..03d918cc36a6 100644 --- a/tests/reexecute/c/README.md +++ b/tests/reexecute/c/README.md @@ -45,7 +45,8 @@ export AWS_REGION=us-east-2 If running locally, metrics collection can be customized via the following parameters: - `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`: if set, determines the port the Prometheus server will listen to (set to `0` by default). +- `METRICS_COLLECTOR_ENABLED`: starts a Prometheus collector. If `METRICS_SERVER_ENABLED` is not set, enabling the collector implicitly sets `METRICS_SERVER_ENABLED` to `true`. 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 605b26db9b42..124ad589e571 100644 --- a/tests/reexecute/c/vm_reexecute_test.go +++ b/tests/reexecute/c/vm_reexecute_test.go @@ -64,6 +64,7 @@ var ( labelsArg string metricsServerEnabledArg bool + metricsServerPortArg uint64 metricsCollectorEnabledArg bool networkUUID string = uuid.NewString() @@ -105,6 +106,7 @@ func TestMain(m *testing.M) { flag.DurationVar(&executionTimeout, "execution-timeout", 0, "Benchmark execution timeout. After this timeout has elapsed, terminate the benchmark without error. If 0, no timeout is applied.") flag.BoolVar(&metricsServerEnabledArg, "metrics-server-enabled", false, "Whether to enable the metrics server.") + flag.Uint64Var(&metricsServerPortArg, "metrics-server-port", 0, "The port the metrics server will listen to.") 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.StringVar(&labelsArg, "labels", "", "Comma separated KV list of metric labels to attach to all exported metrics. Ex. \"owner=tim,runner=snoopy\"") @@ -119,9 +121,8 @@ func TestMain(m *testing.M) { flag.Parse() - if metricsCollectorEnabledArg && !metricsServerEnabledArg { - fmt.Fprint(os.Stderr, "metrics collector is enabled but metrics server is disabled.\n") - os.Exit(1) + if metricsCollectorEnabledArg { + metricsServerEnabledArg = true } customLabels, err := parseCustomLabels(labelsArg) @@ -158,6 +159,7 @@ func BenchmarkReexecuteRange(b *testing.B) { endBlockArg, chanSizeArg, metricsServerEnabledArg, + metricsServerPortArg, metricsCollectorEnabledArg, ) }) @@ -172,6 +174,7 @@ func benchmarkReexecuteRange( endBlock uint64, chanSize int, metricsServerEnabled bool, + metricsPort uint64, metricsCollectorEnabled bool, ) { r := require.New(b) @@ -192,7 +195,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 +568,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",