From 79f4132b4f7d306951f34d72534c5332bb49c75c Mon Sep 17 00:00:00 2001 From: atlas Date: Mon, 24 Aug 2026 16:06:22 +0200 Subject: [PATCH] fix(swarm-nats): the metrics exporter needs a collector flag or it exits MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit prometheus-nats-exporter has never served a metric. Upstream's module renders `-addr … -port … ${extraFlags} ${url}` and defaults extraFlags to the empty list, but the binary refuses to start without at least one collector: it exits 1 with "no Collectors specified". So the unit logged Started, the process was gone milliseconds later, and every scrape was refused -- up=0 continuously, scrape_duration 0.6ms, zero samples. Verified by running the exact argv both ways: without a collector it exits 1, with -varz it stays up and logs the listener. A bogus flag is rejected with exit 2, so the check measures acceptance rather than tolerance. varz is the server itself, connz makes a client that will not stay connected visible, and jsz covers JetStream, which this swarm uses for the status KV. The rest describe a clustered deployment we do not have. An empty list is not a neutral default when the program requires a flag, and nothing about it is visible to evaluation -- which is why the gate now reads the rendered ExecStart rather than only asserting enable. --- nix/host-modules/swarm-nats.nix | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/nix/host-modules/swarm-nats.nix b/nix/host-modules/swarm-nats.nix index 671c2d8e..5c97dccc 100644 --- a/nix/host-modules/swarm-nats.nix +++ b/nix/host-modules/swarm-nats.nix @@ -603,6 +603,27 @@ in listenAddress = "127.0.0.1"; port = cfg.metricsPort; url = "http://127.0.0.1:${toString cfg.monitorPort}"; + + # ⚠️ NOT optional, despite the name. Upstream renders + # `-addr … -port … ${extraFlags} ${url}` and defaults + # `extraFlags` to the empty list, but the exporter REFUSES TO + # START without at least one collector: it exits 1 with + # "no Collectors specified". Shipped without this the unit logs + # `Started`, the process is gone milliseconds later, and the + # scrape is refused — measured, and invisible to evaluation + # because the empty list renders perfectly. + # + # Which three, and why not more: `varz` is the server itself + # (uptime, memory, slow consumers), `connz` is per-connection so + # a client that will not stay connected is visible, and `jsz` + # covers JetStream, which this swarm relies on for the status + # KV. The remaining collectors describe a clustered deployment + # this swarm does not have. + extraFlags = [ + "-varz" + "-connz" + "-jsz=all" + ]; }; # A wrapper that includes upstream's rendered settings verbatim