diff --git a/nix/host-modules/otel.nix b/nix/host-modules/otel.nix index 19a44f6a..2b6c32a1 100644 --- a/nix/host-modules/otel.nix +++ b/nix/host-modules/otel.nix @@ -489,6 +489,18 @@ in }; }; + # Converts any DELTA-temporality counter to CUMULATIVE before it + # leaves this hive. `hive-metric` counters are delta by default + # (agent ergonomics — see its own docs); the swarm's store + # (VictoriaMetrics) has no `deltatocumulative` of its own and + # official guidance is to feed it cumulative. Default config + # (`{ }`) is a no-op passthrough for anything already cumulative + # — Claude Code's own export, `hostmetrics`, and any Prometheus + # scrape all stay exactly as they were. Verified against the + # collector binary rather than assumed: an empty config validates + # clean, an invalid key is rejected (`otelcol-contrib validate`). + processors.deltatocumulative = { }; + service.pipelines.metrics = { # EXTENDED, not replaced. Assigning here instead of appending # would drop `otlp` — the hive would stop receiving from its @@ -512,8 +524,12 @@ in # samples scraped from a target both arrive at the store with # the identity of the machine that collected them, and a # reading is only comparable across hives once it says where - # it came from. - processors = [ "resourcedetection" ]; + # it came from. `deltatocumulative` first, so a delta counter is + # already fixed up by the time it picks up its host identity. + processors = [ + "deltatocumulative" + "resourcedetection" + ]; exporters = [ swarmName ]; }; }