hive collector runs only on hive hosts; review classifier pushes metrics through its forwarder
This commit is contained in:
parent
03796f1964
commit
0cbfa806d3
9 changed files with 191 additions and 98 deletions
|
|
@ -85,6 +85,13 @@ let
|
|||
deploy.review-classifier.enable = true;
|
||||
};
|
||||
|
||||
# The same classifier on a host that runs a hive: its metrics path is the
|
||||
# same as without one.
|
||||
withClassifierOnHive = hiveWithController {
|
||||
deploy.bao.enable = true;
|
||||
deploy.review-classifier.enable = true;
|
||||
};
|
||||
|
||||
# The host fetches that restart their consumer when the store's value
|
||||
# changes (../host-modules/lib/refresh-consumer.nix), each on a fixture
|
||||
# that renders it.
|
||||
|
|
@ -142,12 +149,11 @@ let
|
|||
let
|
||||
es = swarmServiceEnables bare;
|
||||
in
|
||||
# `otel` is the hive tier, which every hive runs and so `bare` does
|
||||
# too: it is the control that the lookup finds what is there, and the
|
||||
# other eight are the swarm's shared services.
|
||||
lib.length (lib.attrNames es) == 9
|
||||
&& es.otel
|
||||
&& !lib.any lib.id (lib.attrValues (removeAttrs es [ "otel" ]));
|
||||
# The hosting switch's host is the control that the lookup finds what
|
||||
# is there.
|
||||
lib.length (lib.attrNames es) == 8
|
||||
&& !lib.any lib.id (lib.attrValues es)
|
||||
&& lib.all lib.id (lib.attrValues (swarmServiceEnables shared.servicesHere));
|
||||
}
|
||||
{
|
||||
name = "the all-local mode turns the swarm controller on";
|
||||
|
|
@ -716,6 +722,64 @@ let
|
|||
lib.attrValues withClassifier.systemd.services
|
||||
));
|
||||
}
|
||||
{
|
||||
# The collector the classifier's metrics reach is the container's own
|
||||
# forwarder, which holds the service's client, so the path is the same
|
||||
# with or without a hive on the host. The logs pipeline is the control
|
||||
# that the lookup finds what is there.
|
||||
name = "the review classifier pushes its metrics to the swarm collector through its own forwarder, with or without a hive";
|
||||
ok =
|
||||
let
|
||||
check =
|
||||
h:
|
||||
let
|
||||
c = h.containers.swarm-review-classifier.config;
|
||||
s = c.services.opentelemetry-collector.settings;
|
||||
otel = h.services.hyperhive.swarm.otel;
|
||||
in
|
||||
c.systemd.services.swarm-review-classifier.environment.OTEL_EXPORTER_OTLP_ENDPOINT
|
||||
== "http://127.0.0.1:4318"
|
||||
&& s.receivers.otlp.protocols.http.endpoint == "127.0.0.1:4318"
|
||||
&& s.service.pipelines.metrics.receivers == [ "otlp" ]
|
||||
&& s.service.pipelines.metrics.exporters == [ "otlphttp" ]
|
||||
&& s.exporters.otlphttp.endpoint == "https://${otel.domain}/swarm-review-classifier"
|
||||
&& s.exporters.otlphttp.auth.authenticator == "oauth2client/swarm"
|
||||
&& s.service.pipelines.logs.receivers == [ "journald" ];
|
||||
in
|
||||
check withClassifier && check withClassifierOnHive;
|
||||
}
|
||||
{
|
||||
# Only the classifier asks the forwarder for a metrics receiver; the
|
||||
# others carry a journal. The classifier is the control.
|
||||
name = "a service forwarder without an OTLP port has no metrics pipeline";
|
||||
ok =
|
||||
let
|
||||
s = withCi.containers.swarm-ci-runner.config.services.opentelemetry-collector.settings;
|
||||
c =
|
||||
withClassifier.containers.swarm-review-classifier.config.services.opentelemetry-collector.settings;
|
||||
in
|
||||
c.service.pipelines ? metrics && !(s.service.pipelines ? metrics) && !(s.receivers ? otlp);
|
||||
}
|
||||
{
|
||||
# The hive tier is the labelling point for a hive's telemetry, so it runs
|
||||
# where a hive does and nowhere else. A services host with no hive keeps
|
||||
# its swarm collector and loses only the host-level one.
|
||||
name = "the hive collector runs on a hive host and not on a swarm-services host without one";
|
||||
ok =
|
||||
let
|
||||
bridge = bare.services.hyperhive.network.bridgeIp;
|
||||
in
|
||||
bare.services.hyperhive.otel.collector.enable
|
||||
&& bare.services.opentelemetry-collector.enable
|
||||
&&
|
||||
bare.services.opentelemetry-collector.settings.receivers.otlp.protocols.http.endpoint
|
||||
== "${bridge}:4318"
|
||||
&& shared.swarmServicesWithController.services.opentelemetry-collector.enable
|
||||
&& !shared.servicesHere.services.hyperhive.otel.collector.enable
|
||||
&& !shared.servicesHere.services.opentelemetry-collector.enable
|
||||
&& lib.elem "hive-collector.hive" bare.services.hyperhive.gateway.localNames
|
||||
&& !(lib.elem "hive-collector.hive" shared.servicesHere.services.hyperhive.gateway.localNames);
|
||||
}
|
||||
{
|
||||
# See the same case in ./builder.nix.
|
||||
name = "the review classifier's container runs the leaf-minting unit before every start";
|
||||
|
|
|
|||
|
|
@ -208,12 +208,9 @@ let
|
|||
# the two tier cases differ only in which receiver they hand it.
|
||||
carriesJournaldSeverity = receiver: lib.elem journaldSeverityParser (receiver.operators or [ ]);
|
||||
|
||||
# The enables that switch owns. ⚠️ `otel` is the per-hive collector's own
|
||||
# option and is NOT under `deploy` — spelled at the wrong path it would be
|
||||
# undeclared rather than false, and a roster that quietly loses a member is
|
||||
# what the count guard in the cases below exists to catch. Its membership
|
||||
# here is deliberate and was the fix for a gap, not an oversight: the hive
|
||||
# tier lands wherever the swarm services do.
|
||||
# The enables that switch owns. The hive tier's collector is not among them: it
|
||||
# follows `deploy.hive-controller.enable`, and a services host without a hive
|
||||
# runs none.
|
||||
swarmServiceEnables =
|
||||
machine:
|
||||
let
|
||||
|
|
@ -221,7 +218,6 @@ let
|
|||
in
|
||||
{
|
||||
matrix = h.deploy.matrix.enable;
|
||||
otel = h.otel.collector.enable;
|
||||
authelia = h.deploy.authelia.enable;
|
||||
nats = h.deploy.nats.enable;
|
||||
swarm-otel = h.deploy.swarm-otel.enable;
|
||||
|
|
|
|||
|
|
@ -207,7 +207,7 @@ let
|
|||
let
|
||||
es = swarmServiceEnables swarmServicesHere;
|
||||
in
|
||||
lib.length (lib.attrNames es) == 9 && lib.all lib.id (lib.attrValues es);
|
||||
lib.length (lib.attrNames es) == 8 && lib.all lib.id (lib.attrValues es);
|
||||
}
|
||||
{
|
||||
# The container is the control that the toggle reaches the module, not
|
||||
|
|
@ -1211,7 +1211,6 @@ let
|
|||
readers = [
|
||||
"swarm-bao-forge-oidc"
|
||||
"swarm-bao-matrix-oidc"
|
||||
"swarm-bao-hive-otel-oidc"
|
||||
"swarm-bao-grafana-oidc"
|
||||
"swarm-bao-grafana-admin"
|
||||
"swarm-bao-grafana-metrics-bearer"
|
||||
|
|
@ -1240,7 +1239,7 @@ let
|
|||
!(lib.any (n: lib.elem n (s.after ++ s.wants ++ s.requires)) storeUnits);
|
||||
in
|
||||
lib.all waits readers
|
||||
&& lib.length readersHere == 10
|
||||
&& lib.length readersHere == 9
|
||||
&& lib.elem "swarm-bao-grafana-admin" readersHere
|
||||
&& lib.length readersElsewhere == 7
|
||||
&& lib.all namesNoStoreUnit readersElsewhere
|
||||
|
|
|
|||
Loading…
Reference in a new issue