From b726848da0d80bfc2d389afd2c62232811b5e64e Mon Sep 17 00:00:00 2001 From: Damien Arnodo Date: Fri, 10 Jul 2026 09:51:48 +0000 Subject: [PATCH] Guard VNI tooltip join against transient duplicate series Wrap the group_left RHS in max by (device, vlan) so a Prometheus restart or relabel change (old/new label-set series briefly coexisting in the staleness window) can't trip PromQL's many-to-many matching error. Closes #50 --- configs/grafana/weathermap-dashboard.json | 2 +- scripts/generate_weathermap.py | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/configs/grafana/weathermap-dashboard.json b/configs/grafana/weathermap-dashboard.json index 61e3f76..a154780 100644 --- a/configs/grafana/weathermap-dashboard.json +++ b/configs/grafana/weathermap-dashboard.json @@ -100,7 +100,7 @@ }, { "refId": "D", - "expr": "count by (device, vlan) (network_instances_network_instance_fdb_mac_table_entries_entry_vlan{device=~\"campus-leaf1|campus-leaf2|campus-leaf3|campus-leaf4|dc-leaf1|dc-leaf2|dc-leaf5|dc-leaf6\"})\n* on(device, vlan) group_left(vlan_to_vni_state_vni)\ninterfaces_interface_arista_vxlan_vlan_to_vnis_vlan_to_vni_state_vni{device=~\"campus-leaf1|campus-leaf2|campus-leaf3|campus-leaf4|dc-leaf1|dc-leaf2|dc-leaf5|dc-leaf6\"}", + "expr": "count by (device, vlan) (network_instances_network_instance_fdb_mac_table_entries_entry_vlan{device=~\"campus-leaf1|campus-leaf2|campus-leaf3|campus-leaf4|dc-leaf1|dc-leaf2|dc-leaf5|dc-leaf6\"})\n* on(device, vlan) group_left(vlan_to_vni_state_vni)\nmax by (device, vlan) (interfaces_interface_arista_vxlan_vlan_to_vnis_vlan_to_vni_state_vni{device=~\"campus-leaf1|campus-leaf2|campus-leaf3|campus-leaf4|dc-leaf1|dc-leaf2|dc-leaf5|dc-leaf6\"})", "legendFormat": "VNI {{device}} {{vlan}}", "datasource": { "type": "prometheus", diff --git a/scripts/generate_weathermap.py b/scripts/generate_weathermap.py index 994c3a6..e470730 100644 --- a/scripts/generate_weathermap.py +++ b/scripts/generate_weathermap.py @@ -352,12 +352,18 @@ def build_weathermap(devices, links, interface_speeds, positions, prometheus_url if vtep_hosts: vtep_regex = "|".join(promql_escape(h) for h in vtep_hosts) # Verbatim join from #44 "VXLAN (MAC count per VNI)", scoped to VTEP nodes. + # RHS is wrapped in max by (device, vlan) so the join key is always + # unique -- a Prometheus restart or relabel change otherwise leaves + # the pre-restart (frozen) and post-restart series briefly coexisting + # within the 5m staleness window, both matching the same (device, + # vlan) group, which trips PromQL's "many-to-many matching not + # allowed" error. See #50. targets.append({ "refId": "D", "expr": ( f'count by (device, vlan) (network_instances_network_instance_fdb_mac_table_entries_entry_vlan{{device=~"{vtep_regex}"}})\n' f'* on(device, vlan) group_left(vlan_to_vni_state_vni)\n' - f'interfaces_interface_arista_vxlan_vlan_to_vnis_vlan_to_vni_state_vni{{device=~"{vtep_regex}"}}' + f'max by (device, vlan) (interfaces_interface_arista_vxlan_vlan_to_vnis_vlan_to_vni_state_vni{{device=~"{vtep_regex}"}})' ), "legendFormat": "VNI {{device}} {{vlan}}", })