nix: attach the prometheus receiver whenever either scrape option is set

The receiver was defined for `scrapeTargets != {} || publishedScrapeTargets
!= {}`, but the swarm-tier pipeline named it only for `scrapeTargets != {}`.
A collector with published targets and no loopback ones therefore rendered
scrape configs that belonged to no pipeline: requested, parsed, delivered
nowhere, and valid enough to deploy.

Latent, not live: the module seeds `scrapeTargets.collector` under its own
`enable`, so the loopback set is never empty in a real deploy and the
disagreeing arm is unreachable today. Nothing would have noticed if that
seeding became conditional, which is why the module-eval case pins the
pipeline rather than trusting the seed to keep masking it.

Refs #4511
This commit is contained in:
atlas 2026-09-19 09:43:30 +02:00 committed by mara
commit fb9a2c0830
2 changed files with 39 additions and 1 deletions

View file

@ -1323,11 +1323,18 @@ in
# producer must always have somewhere to land, unlike
# `prometheus`, which only joins the receiver list once
# something has actually declared a scrape target.
#
# ⚠️ That gate is the SAME condition the receiver is
# defined under, and the two must stay spelled the same
# way: a receiver defined here and attached to no
# pipeline is scrape configs that render, deploy and
# deliver nothing — the silent shape this file keeps
# arguing against, one level up.
"metrics/${swarmTierName}" = {
receivers = [
"otlp/${swarmTierName}"
]
++ lib.optional (cfg.scrapeTargets != { }) "prometheus";
++ lib.optional (cfg.scrapeTargets != { } || cfg.publishedScrapeTargets != { }) "prometheus";
processors = [ "resource/${swarmTierName}" ];
exporters = exporterNames;
};