diff --git a/nix/host-modules/swarm-otel.nix b/nix/host-modules/swarm-otel.nix index 23ae296e..22ebe688 100644 --- a/nix/host-modules/swarm-otel.nix +++ b/nix/host-modules/swarm-otel.nix @@ -77,6 +77,26 @@ in ''; }; + telemetryPort = lib.mkOption { + type = lib.types.port; + default = 8889; + description = '' + Port this collector serves its **own** metrics on — queue depth, + refused and dropped samples, exporter failures. How you find out + that telemetry is being lost, so it is worth keeping rather than + switching off. + + ⚠️ **Deliberately not 8889's neighbour 8888**, which is the + collector's built-in default and therefore what the hive tier + already binds. Two collectors share a network namespace whenever + they are co-located, and unlike the OTLP port this one appears + nowhere in either config — it is a default inside the binary, so + nothing that compares configured ports can see the clash. The + second collector to start simply dies with + `bind: address already in use`. + ''; + }; + url = lib.mkOption { type = lib.types.str; default = "http://127.0.0.1:${toString cfg.port}"; @@ -185,6 +205,23 @@ in // lib.optionalAttrs (otelCfg.protocol == "http/json") { encoding = "json"; }; }; + # Moves this collector's self-metrics off the built-in + # default of `localhost:8888`, which the hive tier holds. + # + # ⚠️ `metrics.address` is the spelling that looks right and + # is REJECTED by this collector version — measured, not + # read: `'migration.MetricsConfigV030' has invalid keys: + # address`. `readers` is the schema it accepts, and the + # difference is a startup failure rather than a warning. + service.telemetry.metrics.readers = [ + { + pull.exporter.prometheus = { + host = "127.0.0.1"; + port = cfg.telemetryPort; + }; + } + ]; + service.pipelines.metrics = { receivers = [ "otlp" ]; # Fan-out, not a choice: with both configured the same