swarm-otel: ship the whole host journal, drop user sessions after it
The swarm collector's journald receiver read only the units listed in `services.hyperhive.swarm.otel.journaldUnits`. A unit nobody listed never reached the store, and a misspelt entry shipped nothing without an error. The list existed to keep an operator's desktop session out of a store every swarm operator can read, but the receiver can only match positively, so the only way to express "not user sessions" was to name every service instead. The receiver now reads the whole host journal, and a new `filter/exclude-user-sessions` processor in the `logs/<swarm>` pipeline drops records whose `_SYSTEMD_SLICE` is `user-<uid>.slice` (session scopes and `user@<uid>.service`). The per-hive `logs/<hive>` pipelines carry agent-container journals only and get no filter. `journaldUnits` is removed with `mkRemovedOptionModule`, together with its non-empty assertion and the entry each host module added. The four module-eval membership checks go with it, replaced by one structural case in swarm-otel-core. Closes #3646
This commit is contained in:
parent
710f5b7b8c
commit
6b1e825c0a
25 changed files with 72 additions and 324 deletions
|
|
@ -62,53 +62,24 @@ let
|
|||
deploy.bao.otelOidcClientKeyFile = "/etc/pki/bao-otel-oidc-key.pem";
|
||||
};
|
||||
|
||||
# The collector beside the store holding a bootstrap token: the one shape in
|
||||
# which every unit an apply can leave failed renders on the same host.
|
||||
otelApplyPath = hive {
|
||||
deploy.swarm-otel.enable = true;
|
||||
deploy.authelia.enable = true;
|
||||
deploy.bao.enable = true;
|
||||
deploy.bao.bootstrapTokenFile = "/run/secrets/bao-bootstrap.token";
|
||||
};
|
||||
|
||||
# Units on the path a deploy takes to TLS, the store's grants and the
|
||||
# collector itself. A failure among them silences ingest, so without their
|
||||
# journals the store can show that ingest stopped but not which unit
|
||||
# stopped it.
|
||||
applyPathUnits = [
|
||||
"container@swarm-otel"
|
||||
"hive-tls-ca"
|
||||
"swarm-services-cert"
|
||||
"hive-gateway-self-signed-cert"
|
||||
"swarm-bao-granter-role"
|
||||
"swarm-bao-controller-policy"
|
||||
"swarm-bao-secret-publisher-policy"
|
||||
"swarm-bao-matrix-ctl-policy"
|
||||
"swarm-bao-matrix-token-policy"
|
||||
"swarm-bao-queue-agent-policy"
|
||||
"swarm-bao-grafana-oidc-policy"
|
||||
"swarm-bao-otel-oidc-policy"
|
||||
"swarm-bao-services-issuer-policy"
|
||||
];
|
||||
cases = [
|
||||
{
|
||||
# Listed AND defined, because a name that matches nothing is not an
|
||||
# error anywhere: a unit renamed out from under its entry would pass a
|
||||
# membership check and still never reach the store.
|
||||
name = "every unit on the apply path is defined and ships its journal";
|
||||
# The host journal is read whole, so the filter is the only thing
|
||||
# keeping an operator's desktop session out of the store. A processor a
|
||||
# pipeline names but the config does not define is a collector that
|
||||
# refuses to start, hence both halves.
|
||||
name = "the host journal ships every unit, through the user-session filter";
|
||||
ok =
|
||||
let
|
||||
m = otelApplyPath;
|
||||
s = otelSettings otelNoStores;
|
||||
journalPipelines = lib.filter (p: builtins.elem "journald" p.receivers) (
|
||||
lib.attrValues s.service.pipelines
|
||||
);
|
||||
in
|
||||
lib.all (
|
||||
u: builtins.elem u m.services.hyperhive.swarm.otel.journaldUnits && m.systemd.services ? ${u}
|
||||
) applyPathUnits;
|
||||
}
|
||||
{
|
||||
# Transient, so nothing here defines it and only membership can be
|
||||
# pinned: nixos-rebuild names the unit it runs the activation in.
|
||||
name = "the activation's journal ships beside the units it starts";
|
||||
ok = builtins.elem "nixos-rebuild-switch-to-configuration" otelApplyPath.services.hyperhive.swarm.otel.journaldUnits;
|
||||
!(s.receivers.journald ? units)
|
||||
&& journalPipelines != [ ]
|
||||
&& lib.all (p: builtins.elem "filter/exclude-user-sessions" p.processors) journalPipelines
|
||||
&& s.processors."filter/exclude-user-sessions".logs.log_record or [ ] != [ ];
|
||||
}
|
||||
{
|
||||
# 🩸 The arm that guards the ruling this slice landed under, the
|
||||
|
|
|
|||
Loading…
Reference in a new issue