From b5efe1f9a9ed86473375654c43ae499583eaece5 Mon Sep 17 00:00:00 2001 From: charliez Date: Mon, 3 Aug 2026 20:58:35 -0700 Subject: [PATCH 1/2] Label y-axis units on stress-test CPU and inode panels Fixes #69944 The CPU Usage panels (Master, Minion 1-3, API) use Grafana's percentunit, a 0-1 ratio where 1.0 == 1 full CPU core -- matching rate(container_cpu_usage_seconds_total[...]) semantics from cAdvisor. Without a label, a value like 1.2 is easy to misread as "1.2% of the host" rather than 1.2 CPU cores. The Minion Inodes panels use Grafana's "short" unit (a plain count) and also had no y-axis label. render_panels.py already special-cases bytes-family units to convert to MB and label the axis; this follows the same pattern for percentunit and short so every rendered panel states what its numbers mean. --- .gitignore | 1 + tests/monitoring/render_panels.py | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/.gitignore b/.gitignore index 21257ad4d499..6d7607c5d284 100644 --- a/.gitignore +++ b/.gitignore @@ -166,3 +166,4 @@ nox.*.tar.xz /.gemini venv311/ venv312/ +.cursor-ai/ diff --git a/tests/monitoring/render_panels.py b/tests/monitoring/render_panels.py index 00a46a159fc6..70a297410489 100644 --- a/tests/monitoring/render_panels.py +++ b/tests/monitoring/render_panels.py @@ -122,6 +122,14 @@ def _bytes_unit(unit_hint: str) -> bool: return unit_hint.lower() in ("bytes", "decbytes", "kbytes", "mbytes", "gbytes") +def _is_percentunit(unit_hint: str) -> bool: + return unit_hint.lower() == "percentunit" + + +def _is_count_unit(unit_hint: str) -> bool: + return unit_hint.lower() == "short" + + def render_panel(panel: dict, end_ts: float) -> plt.Figure | None: """Return a matplotlib Figure for ``panel``, or ``None`` if no series.""" targets = panel.get("targets") or [] @@ -130,6 +138,8 @@ def render_panel(panel: dict, end_ts: float) -> plt.Figure | None: unit_hint = panel.get("fieldConfig", {}).get("defaults", {}).get("unit") or "" is_bytes = _bytes_unit(unit_hint) + is_percentunit = _is_percentunit(unit_hint) + is_count = _is_count_unit(unit_hint) fig, ax = plt.subplots(figsize=(11, 4)) series_count = 0 @@ -165,6 +175,14 @@ def render_panel(panel: dict, end_ts: float) -> plt.Figure | None: ax.set_title(panel.get("title") or "panel", fontsize=11) if is_bytes: ax.set_ylabel("MB") + elif is_percentunit: + # Grafana's percentunit is a 0-1 ratio (1.0 == 1 CPU core, not 1% of + # the host); rate(container_cpu_usage_seconds_total[...]) values here + # are already in that ratio, so label explicitly to avoid confusing + # "1.2" with "1.2% of the host" instead of 1.2 CPU cores. + ax.set_ylabel("CPU cores (1.0 = 1 core)") + elif is_count: + ax.set_ylabel("count") ax.xaxis.set_major_formatter(DateFormatter("%H:%M")) ax.tick_params(axis="x", rotation=30, labelsize=8) ax.tick_params(axis="y", labelsize=8) From 942e715f29211c4e3a1a237ef21701ed98a5bd43 Mon Sep 17 00:00:00 2001 From: charliez Date: Wed, 5 Aug 2026 16:03:07 -0700 Subject: [PATCH 2/2] Revert unrelated .gitignore entry .cursor-ai/ was accidentally picked up while preparing this branch and is unrelated to the y-axis label fix. --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index 6d7607c5d284..21257ad4d499 100644 --- a/.gitignore +++ b/.gitignore @@ -166,4 +166,3 @@ nox.*.tar.xz /.gemini venv311/ venv312/ -.cursor-ai/