docs/services: the store export is unconditional, and there is no eval refusal

`5478e0bf` (`fix(#3554)`) made both store exporters unconditional and removed
the "somewhere to send" assertion, and touched no documentation — its diffstat
is four `nix/` files. `services.md` § *Telemetry collector (OTEL)* still
described the old shape in two places.

① "it writes the store above and exports to `otel.endpoint`, doing both when
both are configured" — only the upstream is conditional. `exporterNames`
(swarm-otel.nix:231) always carries the store exporter, with a comment saying
why: `deploy.victoriametrics.enable` means "this host RUNS the store", and a
swarm has one either way.

② "With neither `otel.endpoint` nor the store enabled, this module refuses the
collector at eval" — that assertion is gone. swarm-otel.nix:693 records the
removal at the head of the assertions list, and `5478e0bf`'s message states it
was a ruling rather than an oversight: a collector on a host of its own is a
supported shape, so refusing to build it would have made the fix illegal
exactly where the bug bit hardest. `git grep` finds no surviving assertion of
that shape.

The replacement paragraph states the invariant an operator can act on — the
exporters have no gate, the stores are addressed by swarm name — and keeps the
failure it prevents, since "an absent exporter is not an error" is the part that
made the old bug silent.

The stale claim dates to `80c9118f` (2026-08-18), 13 days before the behaviour
changed under it.

Closes #4214.
This commit is contained in:
atlas 2026-09-11 13:32:25 +02:00 committed by mara
commit c234a32b36

View file

@ -156,10 +156,9 @@ intended writer.
### Telemetry collector (OTEL) ### Telemetry collector (OTEL)
The swarm's collector receives from every hive's own collector and is the The swarm's collector receives from every hive's own collector and is the
only process that decides where telemetry goes: it writes the store above only process that decides where telemetry goes: it always writes the stores
and exports to `otel.endpoint`, doing both when both are configured. It above, and exports to `otel.endpoint` as well when that's set. It holds
also holds the upstream credential, which is why no hive and no agent the upstream credential, which is why no hive and no agent needs one.
needs one.
It runs in a `swarm-otel` container. Its `swarm.otel.port` defaults to It runs in a `swarm-otel` container. Its `swarm.otel.port` defaults to
`4319` rather than OTLP's usual `4318`, which the hive tier uses — swarm `4319` rather than OTLP's usual `4318`, which the hive tier uses — swarm
@ -178,9 +177,11 @@ gateway either way.
| `swarm.otel.domain` | Only to rename it — the default already resolves correctly for every hive in the swarm. | | `swarm.otel.domain` | Only to rename it — the default already resolves correctly for every hive in the swarm. |
| `swarm.otel.port` | Only if something else on the services host already claims `4319`. | | `swarm.otel.port` | Only if something else on the services host already claims `4319`. |
With neither `otel.endpoint` nor the store enabled, this module refuses **Both store exporters are unconditional**, and `deploy.victoriametrics.enable`
the collector at eval — a tier that receives samples and drops them doesn't gate them: that option says this host _runs_ the store, while the swarm
looks healthy while losing data. has one either way, reached by its swarm name through the gateway. Gating on it
once left a collector on any other host with no exporter at all — receiving from
every hive and dropping it, silently, because an absent exporter isn't an error.
Agent-side configuration, and what a hive's own collector does, are in Agent-side configuration, and what a hive's own collector does, are in
[`../scheduler/observability.md`](../scheduler/observability.md). [`../scheduler/observability.md`](../scheduler/observability.md).