From 40af073d9c999d877da04eb63889407dc517767b Mon Sep 17 00:00:00 2001 From: Your Name Date: Thu, 21 May 2026 19:21:22 -0400 Subject: [PATCH] alloy: add prometheus.exporter.unix canary (Track A fleet rollout) Embeds node_exporter inside Alloy alongside Loki shipping; pushes metrics via remote_write to observe Prom with job=node_lxc_canary to run side-by-side with the existing node_exporter scrape until cutover. See homelab-docs/docs/audit/alloy-consolidation-2026-05-21.md. --- roles/alloy/templates/config.alloy.j2 | 46 +++++++++++++++++++++++++++ vars/main.yml | 6 ++++ 2 files changed, 52 insertions(+) diff --git a/roles/alloy/templates/config.alloy.j2 b/roles/alloy/templates/config.alloy.j2 index b1d1225..19f6b8e 100644 --- a/roles/alloy/templates/config.alloy.j2 +++ b/roles/alloy/templates/config.alloy.j2 @@ -39,3 +39,49 @@ loki.write "default" { url = "{{ alloy_loki_url }}" } } + +// ============================================================ +// Prometheus — embedded node_exporter (replaces standalone). +// Bare-metal Alloy on systemd; reads /proc, /sys, / natively +// (no /host/* bind mounts; no pid:host needed). +// ============================================================ + +prometheus.exporter.unix "node" { + // Defaults: rootfs_path=/, procfs_path=/proc, sysfs_path=/sys +} + +prometheus.scrape "node" { + targets = prometheus.exporter.unix.node.targets + forward_to = [prometheus.relabel.node.receiver] + scrape_interval = "15s" + job_name = "{{ alloy_prom_job | default('node_lxc') }}" +} + +// Alloy's exporter sets job=integrations/unix and the targets carry no +// instance label by default. Rewrite to match the historical Prometheus +// scrape labels so existing dashboards keep working. +prometheus.relabel "node" { + forward_to = [prometheus.remote_write.observe.receiver] + rule { + target_label = "instance" + replacement = "{{ alloy_prom_instance | default(ansible_default_ipv4.address + ':9100') }}" + } + rule { + target_label = "job" + replacement = "{{ alloy_prom_job | default('node_lxc') }}" + } + rule { + target_label = "group" + replacement = "{{ alloy_prom_group | default('lxc') }}" + } + rule { + target_label = "hostname" + replacement = "{{ alloy_prom_hostname | default(alloy_host_label) }}" + } +} + +prometheus.remote_write "observe" { + endpoint { + url = "{{ alloy_prom_remote_write | default('http://observe.lan.balders.ca:9090/api/v1/write') }}" + } +} diff --git a/vars/main.yml b/vars/main.yml index ce49123..fa297d4 100644 --- a/vars/main.yml +++ b/vars/main.yml @@ -31,6 +31,12 @@ ssh_authorized_keys: # this LXC — bare-metal systemd Alloy via Grafana apt repo. alloy_host_label: meridian alloy_loki_url: http://observe.lan.balders.ca:3100/loki/api/v1/push +# Track A canary: _canary suffix lets the embedded exporter run in +# parallel with the existing node_exporter scrape — once parity is +# verified, flip this to node_lxc and decommission node_exporter. +alloy_prom_job: node_lxc_canary +alloy_prom_group: lxc +alloy_prom_hostname: meridian # Meridian meridian_user: meridian