From ff3ff04259b281437ad5cba4cb366e13c73f3bb8 Mon Sep 17 00:00:00 2001 From: Chrysostomos Nanakos Date: Mon, 6 Apr 2026 16:33:21 +0300 Subject: [PATCH] feat: enable metrics and log blocks served per node after each experiment Signed-off-by: Chrysostomos Nanakos --- benchmarks/codex/codex_node.py | 13 +++++++++++++ .../experiments/dissemination_experiment/static.py | 12 +++++++++++- benchmarks/logging/logging.py | 5 +++++ k8s/charts/codex/templates/codex-statefulset.yaml | 6 ++++++ 4 files changed, 35 insertions(+), 1 deletion(-) diff --git a/benchmarks/codex/codex_node.py b/benchmarks/codex/codex_node.py index 5865cb3..9dc979c 100644 --- a/benchmarks/codex/codex_node.py +++ b/benchmarks/codex/codex_node.py @@ -112,6 +112,19 @@ class CodexNode(Node[Cid, CodexMeta], ExperimentComponent): return response.iter_content(chunk_size=chunk_size) + def blocks_sent(self, metrics_port: int = 8008) -> int: + """Query the Prometheus metrics endpoint for blocks sent count.""" + try: + metrics_url = self.codex_api_url._replace(port=metrics_port, path="/metrics") + response = requests.get(str(metrics_url), timeout=5) + response.raise_for_status() + for line in response.text.splitlines(): + if line.startswith("storage_block_exchange_blocks_sent_total"): + return int(float(line.split()[1])) + except Exception: + pass + return 0 + def wipe_all_datasets(self): for dataset in list(self.hosted_datasets): self.remove(dataset) diff --git a/benchmarks/core/experiments/dissemination_experiment/static.py b/benchmarks/core/experiments/dissemination_experiment/static.py index 992fd3f..fd4eb9d 100644 --- a/benchmarks/core/experiments/dissemination_experiment/static.py +++ b/benchmarks/core/experiments/dissemination_experiment/static.py @@ -15,7 +15,7 @@ from benchmarks.core.network import ( Node, DownloadHandle, ) -from benchmarks.logging.logging import RequestEvent, EventBoundary +from benchmarks.logging.logging import RequestEvent, EventBoundary, BlocksServedMetric logger = logging.getLogger(__name__) @@ -119,6 +119,16 @@ class StaticDisseminationExperiment( ] ) + with experiment_stage(self, "blocks_served"): + for i, node in enumerate(self.nodes): + if hasattr(node, "blocks_sent"): + logger.info( + BlocksServedMetric( + node=node.name, + value=node.blocks_sent(), + ) + ) + with experiment_stage(self, "log_cooldown"): # FIXME this is a hack to ensure that nodes get a chance to log their data before we # run the teardown hook and remove the torrents. diff --git a/benchmarks/logging/logging.py b/benchmarks/logging/logging.py index 9da11a1..b50c3ba 100644 --- a/benchmarks/logging/logging.py +++ b/benchmarks/logging/logging.py @@ -249,6 +249,10 @@ class DownloadMetric(Metric): dataset_name: str +class BlocksServedMetric(Metric): + name: str = "blocks_served" + + class EventBoundary(Enum): start = "start" end = "end" @@ -279,6 +283,7 @@ def basic_log_parser() -> LogParser: parser.register(NodeEvent) parser.register(Metric) parser.register(DownloadMetric) + parser.register(BlocksServedMetric) parser.register(RequestEvent) parser.register(ExperimentStatus) parser.register(ExperimentStage) diff --git a/k8s/charts/codex/templates/codex-statefulset.yaml b/k8s/charts/codex/templates/codex-statefulset.yaml index f8ddf7c..f928092 100644 --- a/k8s/charts/codex/templates/codex-statefulset.yaml +++ b/k8s/charts/codex/templates/codex-statefulset.yaml @@ -65,6 +65,12 @@ spec: fieldPath: metadata.name - name: STORAGE_NAT value: "none" + - name: STORAGE_METRICS + value: "true" + - name: STORAGE_METRICS_ADDRESS + value: "0.0.0.0" + - name: STORAGE_METRICS_PORT + value: "8008" - name: STORAGE_BLOCK_TTL value: {{ .Values.experiment.blockTTL | quote }} - name: STORAGE_BLOCK_MI