diff --git a/nix/host-modules/otel.nix b/nix/host-modules/otel.nix index 66d89855..75e3ec49 100644 --- a/nix/host-modules/otel.nix +++ b/nix/host-modules/otel.nix @@ -181,6 +181,23 @@ let otel = config.services.hyperhive.otel; listen = "${config.services.hyperhive.network.bridgeIp}:${toString otel.collector.port}"; + # `otel.protocol` describes the UPSTREAM link and always did. + # Inserting a collector splits the path in two, and the + # upstream half is the one that has to keep honouring it — so + # the exporter is chosen by it, rather than the option quietly + # becoming "how agents talk to the collector". The agent half + # is pinned to OTLP/HTTP by the receiver below (derived in + # hive-c0re/environment.nix). + grpcUpstream = otel.protocol == "grpc"; + upstreamName = if grpcUpstream then "otlp" else "otlphttp"; + upstream = { + endpoint = otel.endpoint; + # The value is interpolated by the collector at runtime from + # its environment, never by nix. `EnvironmentFile` below is + # what puts it there. + headers.${otel.collector.upstreamHeaderName} = "\${env:${otel.collector.upstreamHeaderName}}"; + } + // lib.optionalAttrs (otel.protocol == "http/json") { encoding = "json"; }; in { assertions = [ @@ -215,16 +232,10 @@ validateConfigFile = true; settings = { receivers.otlp.protocols.http.endpoint = listen; - exporters.otlphttp = { - endpoint = otel.endpoint; - # The value is interpolated by the collector at runtime - # from its environment, never by nix. `EnvironmentFile` - # below is what puts it there. - headers.${otel.collector.upstreamHeaderName} = "\${env:${otel.collector.upstreamHeaderName}}"; - }; + exporters.${upstreamName} = upstream; service.pipelines.metrics = { receivers = [ "otlp" ]; - exporters = [ "otlphttp" ]; + exporters = [ upstreamName ]; }; }; };