I’d like to share nixos-telemetry, a NixOS flake that makes setting up observability in your infrastructure easy. An OpenTelemetry collector sits at the center of each machine. Scrapers, storage, and visualization are all opt-in. You enable what you need; the collector wires the pipeline together automatically.
Why?
Wiring up telemetry in NixOS today means gluing together Telegraf, Prometheus, Loki, Grafana, Alloy, each with its own config format, ports, and inter-service dependencies. nixos-telemetry puts all of that behind a single telemetry.* option tree:
Turn on the system with telemetry.enable = true.
Every app is opt-in. Nothing starts that you didn’t ask for.
The collector starts automatically once a complete pipeline exists, a matching source and sink for the same signal type. No sink? It waits.
Forward to a remote collector, run a full local stack, or both. Fan-out to multiple sinks is supported.
Regarding Discourse LLM Policy : I must disclose that substantial parts of this project are llm generated. And because I coppied parts of the README in this post, substantial parts of this announcmement too.
Maybe, don’t know. I mean it would be possible to bring this to nixpkgs. For example by introducing an option like telemetry.enable or monitoring.enable, and if it’s true, automatic wiring against opentelemetry collector will be done if service.grafana, service.loki or service.telegraf is enabled.
Couldn’t this just be a single NixOS module compositionally importing your ./modules directory of NixOS modules? That would free users from needing to buy into flakes, flake-parts, & the rest of the tooling… This also makes it available to folks not using x86 or aarch limited to just Darwin & Linux.
Well that would then mean all downstream users need to accept your tooling too transitively like treefmt, flake parts, devshell (without setting flake = false; that is, but…). But the default.nix you show was exactly what I was looking for—which is a ‘super’ module importing the others & is independent of any additional tooling, flakes, systems. You should add a not eabout this to the docs as there is no mention of import like imports = [ "${inputs.nixos-telemetry}/modules" ]. It seems like this should be noted flake = false; should be the preferred method since it avoids extra tooling for downstream.
The implication of course here being that the file layout becomes a part of the API, which can be surprising if you are a flakes-first person.
I’m skeptical of the utility of something like this more broadly, I would assume most people who are arriving at the conclusion that they need an otel collector probably have their own opinions about wiring, and worse, probably has their hands tied in 7 other ways by other constraints outside of their control.
I have nothing against show-cases or sharing, so I don’t want to poo-poo this. I wouldn’t use it. I would probably read it if I were shopping about for how to get started.
Don’t be a flakes-first person. I’ve been using flakes for development but I’ve had the insight: my projects are not consumable as flakes. Only vanilla nix. The flake is for development.
I wrote that because I’ve been bitten more that once consuming a project that had a flake at the root which kept the flake attributes stable but reorganised all of the files (or alternatively changed the attrs available on /default.nix). Not because I run flakes
Just as much, I have been bitten by folk renaming Flake keys. The path doesn’t require experimental features, pull in transitive dependencies, & doesn’t require evaluation—just a 20-year-old, stable import "${path}" feature.
But the problem is that this is worse than the default experience already in nixpkgs
key is world readable because not sourced from file
instead of enforcing a “first login” password we start it open to the world. If you don’t know what shodan is, or how quickly servers get lit up on the internet these days, I recommend you take a look. Every week there is some new service full of data discovered wide open on the internet. We don’t rise to the level of our ambitions, we fail to the level of our systems.
for instance. No world readable store values should contain secrets. Now obviously, this is not generic, it’s cribbed directly from work grafana, but it’s not a huge leap of imagination to get to a generic version that doesn’t start world-open.
About the admin authentication I provided 3 ways to set it up, and the default is login with admin:admin with request to change your password when you login. I want to keep grafana as default and easy to use as possible, and just add option for a more safer (and a more yolo) way.
Hope you like the solution too. Thanks again for your input.
The conditional blog obviously needs cleanup, but the sentence from the documentation should cover it.
Yes Grafana needs definitly some more love, but I had not good idea on how to dumb down the configuration for it. I don’t want to just forward every parameter. But in this case it can’t hurt to forward the http_addr parameter. (update: added this parameter)
About telegraf there are a lot of inputs which are not there yet. My plan is to configure everything based on service.<name>.enable, for example: