From ed8635692800ec88bc38fe8d9926f7a16f33a5bb Mon Sep 17 00:00:00 2001 From: iris Date: Sun, 1 Nov 2026 13:00:47 +0100 Subject: [PATCH] egress board: join the host tables by labels, one row per group labelsToFields and merge left a __name__ column and one row per stat on the multi-stat table. joinByLabels gives a column per stat. --- .../swarm-grafana/dashboards/egress.json | 48 +++++++------------ nix/module-eval/grafana.nix | 15 ++++-- 2 files changed, 28 insertions(+), 35 deletions(-) diff --git a/nix/host-modules/swarm-grafana/dashboards/egress.json b/nix/host-modules/swarm-grafana/dashboards/egress.json index e21f9e46..c5447d8c 100644 --- a/nix/host-modules/swarm-grafana/dashboards/egress.json +++ b/nix/host-modules/swarm-grafana/dashboards/egress.json @@ -798,17 +798,13 @@ ], "transformations": [ { - "kind": "labelsToFields", + "kind": "joinByLabels", "spec": { - "id": "labelsToFields", - "options": {} - } - }, - { - "kind": "merge", - "spec": { - "id": "merge", - "options": {} + "id": "joinByLabels", + "options": { + "join": ["dest"], + "value": "__name__" + } } }, { @@ -1038,17 +1034,13 @@ ], "transformations": [ { - "kind": "labelsToFields", + "kind": "joinByLabels", "spec": { - "id": "labelsToFields", - "options": {} - } - }, - { - "kind": "merge", - "spec": { - "id": "merge", - "options": {} + "id": "joinByLabels", + "options": { + "join": ["agent", "dest"], + "value": "__name__" + } } }, { @@ -1407,17 +1399,13 @@ ], "transformations": [ { - "kind": "labelsToFields", + "kind": "joinByLabels", "spec": { - "id": "labelsToFields", - "options": {} - } - }, - { - "kind": "merge", - "spec": { - "id": "merge", - "options": {} + "id": "joinByLabels", + "options": { + "join": ["agent", "dest", "port"], + "value": "__name__" + } } }, { diff --git a/nix/module-eval/grafana.nix b/nix/module-eval/grafana.nix index ada37531..b4f95f9f 100644 --- a/nix/module-eval/grafana.nix +++ b/nix/module-eval/grafana.nix @@ -496,15 +496,20 @@ let && lib.all (e: lib.hasInfix "\"TCP_\"*" e) ( lib.filter (e: lib.hasInfix access e) (exprs ++ [ agentVar.spec.query.spec.query ]) ) - # A grouped stats query is one frame per group, which a table panel shows as - # a dropdown of series; labels to columns, then a merge, makes the rows. + # A grouped stats query is one frame per group and stat, which a table panel + # shows as a dropdown of series; joining by the group labels, with the stat's + # name as the column, makes one row per group. && lib.all ( e: - map (t: t.spec.id) e.spec.data.spec.transformations == [ - "labelsToFields" - "merge" + let + xf = e.spec.data.spec.transformations; + in + map (t: t.spec.id) xf == [ + "joinByLabels" "organize" ] + && (lib.head xf).spec.options.value == "__name__" + && (lib.head xf).spec.options.join != [ ] ) (lib.filter (e: e.spec.vizConfig.group == "table") (lib.attrValues board.spec.elements)) && lib.hasInfix "logformat would_deny would_deny user=%[un method=%rm host=%>rd port=%>rP result=" squid && lib.hasInfix "access_log syslog:daemon.info squid !manager" squid;