feat(#3554): let a hive-owned service declare a scrape target
This commit is contained in:
parent
9fec1e1dca
commit
ece21b0f7f
1 changed files with 57 additions and 2 deletions
|
|
@ -193,6 +193,41 @@ in
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
scrapeTargets = lib.mkOption {
|
||||||
|
type = lib.types.attrsOf lib.types.str;
|
||||||
|
default = { };
|
||||||
|
example = lib.literalExpression ''{ hive-forge = "127.0.0.1:3000"; }'';
|
||||||
|
description = ''
|
||||||
|
Prometheus exposition endpoints this hive's collector scrapes, as
|
||||||
|
`<job name> = "<host>:<port>"`.
|
||||||
|
|
||||||
|
**A service declares its own entry, from its own module, under its
|
||||||
|
own `enable`** — the same rule as the swarm tier's option of the
|
||||||
|
same name, and for the same reason: an entry exists only where the
|
||||||
|
service that named it runs, so the scraper and its target are
|
||||||
|
co-located by construction rather than by luck.
|
||||||
|
|
||||||
|
⚠️ **This tier, not the swarm one, is where a HIVE-owned target
|
||||||
|
belongs.** The two are not interchangeable: a swarm service does
|
||||||
|
not belong to a hive, so its samples must never acquire a `hive`
|
||||||
|
label — which is why that scraper lives one tier up. Putting a
|
||||||
|
hive-owned target there would either mislabel it or leave it
|
||||||
|
unattributed.
|
||||||
|
|
||||||
|
Scraping is unauthenticated on purpose. This receiver is a
|
||||||
|
prometheus-to-OTLP converter sitting next to what it reads, in the
|
||||||
|
same trust position as the agents already pushing to this
|
||||||
|
collector; the authenticated hop is the collector's own export
|
||||||
|
onward, which is one hop for the whole hive rather than one per
|
||||||
|
target.
|
||||||
|
|
||||||
|
Empty by default, and that is the shipped case — no scrape
|
||||||
|
receiver is emitted at all, because a `prometheus` receiver with
|
||||||
|
nothing to scrape is a config that renders, starts and collects
|
||||||
|
nothing.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
clientSecretFile = lib.mkOption {
|
clientSecretFile = lib.mkOption {
|
||||||
type = lib.types.nullOr lib.types.str;
|
type = lib.types.nullOr lib.types.str;
|
||||||
default =
|
default =
|
||||||
|
|
@ -312,7 +347,20 @@ in
|
||||||
# prove this config STARTS, never mind that a sample arrives.
|
# prove this config STARTS, never mind that a sample arrives.
|
||||||
validateConfigFile = true;
|
validateConfigFile = true;
|
||||||
settings = {
|
settings = {
|
||||||
receivers.otlp.protocols.http.endpoint = listen;
|
receivers = {
|
||||||
|
otlp.protocols.http.endpoint = listen;
|
||||||
|
}
|
||||||
|
# Only when a service has actually declared a target. An enabled
|
||||||
|
# `prometheus` receiver with an empty `scrape_configs` renders,
|
||||||
|
# validates and starts perfectly while reading nothing — and the
|
||||||
|
# empty set is the default, so that inert shape would be what
|
||||||
|
# most hives deploy.
|
||||||
|
// lib.optionalAttrs (otel.scrapeTargets != { }) {
|
||||||
|
prometheus.config.scrape_configs = lib.mapAttrsToList (job: target: {
|
||||||
|
job_name = job;
|
||||||
|
static_configs = [ { targets = [ target ]; } ];
|
||||||
|
}) otel.scrapeTargets;
|
||||||
|
};
|
||||||
|
|
||||||
# One destination, and it is the swarm's collector. This tier
|
# One destination, and it is the swarm's collector. This tier
|
||||||
# holds no upstream credential and writes no store: it receives
|
# holds no upstream credential and writes no store: it receives
|
||||||
|
|
@ -352,7 +400,14 @@ in
|
||||||
service.extensions = lib.optional senderAuth authName;
|
service.extensions = lib.optional senderAuth authName;
|
||||||
|
|
||||||
service.pipelines.metrics = {
|
service.pipelines.metrics = {
|
||||||
receivers = [ "otlp" ];
|
# EXTENDED, not replaced. Assigning here instead of appending
|
||||||
|
# would drop `otlp` — the hive would stop receiving from its
|
||||||
|
# own agents while still rendering a config the collector
|
||||||
|
# starts cleanly on, so nothing would report the loss. The
|
||||||
|
# `optional` matters too: a pipeline naming a receiver that no
|
||||||
|
# longer exists is a startup failure, which `validateConfigFile`
|
||||||
|
# below turns into a build failure rather than a broken deploy.
|
||||||
|
receivers = [ "otlp" ] ++ lib.optional (otel.scrapeTargets != { }) "prometheus";
|
||||||
exporters = [ swarmName ];
|
exporters = [ swarmName ];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue