From 4066c62f27381f475c41be02fabeefea0ac87787 Mon Sep 17 00:00:00 2001 From: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com> Date: Fri, 14 Aug 2026 22:56:58 +0100 Subject: [PATCH 1/2] fix(telemetry): show the network type in the FullBelowCache gauge title Single-value panels carry the filtered network type in their title because they have no legend to put it in; multi-series panels carry it in legendFormat instead. This gauge was the only single-value panel across the fifteen dashboards without it, so its reading was ambiguous once more than one network type was in scope. --- docker/telemetry/grafana/dashboards/node-health.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/telemetry/grafana/dashboards/node-health.json b/docker/telemetry/grafana/dashboards/node-health.json index 5fcde759cd..cf86b02c3f 100644 --- a/docker/telemetry/grafana/dashboards/node-health.json +++ b/docker/telemetry/grafana/dashboards/node-health.json @@ -3017,7 +3017,7 @@ "refId": "A" } ], - "title": "FullBelowCache Hit Rate", + "title": "FullBelowCache Hit Rate [$xrpl_network_type]", "type": "gauge" } ], From 773a5cc0fbdac2e9404a7dcede3e0c49d15bde4c Mon Sep 17 00:00:00 2001 From: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com> Date: Fri, 14 Aug 2026 22:58:58 +0100 Subject: [PATCH 2/2] fix(telemetry): stop the dashboard lint passing when it checked nothing Run with no arguments the script iterated an empty list, found no violations and printed "OK: 0 dashboard(s) passed" with exit 0 -- a clean bill of health for reading no files, indistinguishable from a real pass. A bare run now defaults to every dashboard beside the script, and a run that still ends up with nothing to check exits 2 rather than reporting success. Passing paths explicitly behaves as before. --- .../grafana/dashboards/validate_dashboards.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/docker/telemetry/grafana/dashboards/validate_dashboards.py b/docker/telemetry/grafana/dashboards/validate_dashboards.py index e921d02c4f..f14e5c4524 100755 --- a/docker/telemetry/grafana/dashboards/validate_dashboards.py +++ b/docker/telemetry/grafana/dashboards/validate_dashboards.py @@ -2,6 +2,7 @@ """Dashboard lint: cumulative metrics must be rate()-wrapped; tier filters present.""" import json, re, sys +from pathlib import Path # Prometheus gauges that hold a CUMULATIVE total -> must be rate()/increase()-wrapped. CUMULATIVE_PREFIXES = ( @@ -111,8 +112,23 @@ def check(path, forbid_5m): def main(): + """Validate the dashboards named on the command line, or all of them. + + Exit status: 0 every dashboard passed, 1 violations were found, 2 there was + nothing to validate. The last is an error rather than a pass: reporting + success without having read a single dashboard is indistinguishable from a + clean run, so a caller that mis-spells a path gets a green light for work + that never happened. + """ args = [a for a in sys.argv[1:] if not a.startswith("--")] forbid_5m = "--no-5m" in sys.argv + if not args: + # Default to every dashboard beside this script, so a bare run checks + # the whole set instead of iterating an empty list. + args = sorted(str(p) for p in Path(__file__).resolve().parent.glob("*.json")) + if not args: + print("ERROR: no dashboard JSON files to validate", file=sys.stderr) + sys.exit(2) all_errs = [] for path in args: all_errs += check(path, forbid_5m)