From 8d367a5f2b3ca3f2fab96e3648ff0ea1604404a3 Mon Sep 17 00:00:00 2001 From: kashw2 Date: Mon, 18 Aug 2025 16:37:51 +1000 Subject: [PATCH] nixos/pyroscope: init --- .../manual/release-notes/rl-2605.section.md | 2 + nixos/modules/module-list.nix | 1 + .../modules/services/monitoring/pyroscope.nix | 117 ++++++++++++++++++ 3 files changed, 120 insertions(+) create mode 100644 nixos/modules/services/monitoring/pyroscope.nix diff --git a/nixos/doc/manual/release-notes/rl-2605.section.md b/nixos/doc/manual/release-notes/rl-2605.section.md index d1fe153f0df1..e6396f87431f 100644 --- a/nixos/doc/manual/release-notes/rl-2605.section.md +++ b/nixos/doc/manual/release-notes/rl-2605.section.md @@ -32,6 +32,8 @@ - [DankMaterialShell](https://danklinux.com), a complete desktop shell for Wayland compositors built with Quickshell. Available as [programs.dms-shell](#opt-programs.dms-shell.enable). +- [pyroscope](https://github.com/grafana/pyroscope), a continuous profiling platform. that allows for performance debugging. Available as [services.pyroscope](#opt-services.pyroscope.enable) + - [dms-greeter](https://danklinux.com), a modern display manager greeter for DankMaterialShell that works with greetd and supports multiple Wayland compositors. Available as [services.displayManager.dms-greeter](#opt-services.displayManager.dms-greeter.enable). - [dsearch](https://github.com/AvengeMedia/danksearch), a fast filesystem search service with fuzzy matching. Available as [programs.dsearch](#opt-programs.dsearch.enable). diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index cdd258e5b176..33fcb8d662c9 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -1044,6 +1044,7 @@ ./services/monitoring/prometheus/pushgateway.nix ./services/monitoring/prometheus/sachet.nix ./services/monitoring/prometheus/xmpp-alerts.nix + ./services/monitoring/pyroscope.nix ./services/monitoring/riemann-dash.nix ./services/monitoring/riemann-tools.nix ./services/monitoring/riemann.nix diff --git a/nixos/modules/services/monitoring/pyroscope.nix b/nixos/modules/services/monitoring/pyroscope.nix new file mode 100644 index 000000000000..34e70f9455dd --- /dev/null +++ b/nixos/modules/services/monitoring/pyroscope.nix @@ -0,0 +1,117 @@ +{ + lib, + pkgs, + config, + utils, + ... +}: + +let + cfg = config.services.pyroscope; + settingsFormat = pkgs.formats.yaml { }; +in +{ + meta.maintainers = [ lib.maintainers.kashw2 ]; + + options.services.pyroscope = { + enable = lib.mkEnableOption "Pyroscope"; + + package = lib.mkPackageOption pkgs "pyroscope" { }; + + openFirewall = lib.mkOption { + type = lib.types.bool; + default = false; + description = "Whether or not to open the firewall for this service"; + }; + + settings = lib.mkOption { + type = lib.types.submodule { + freeformType = settingsFormat.type; + options = { + server = { + http_listen_address = lib.mkOption { + type = lib.types.str; + default = "127.0.0.1"; + description = "The server listen address"; + }; + http_listen_port = lib.mkOption { + type = lib.types.port; + default = 4040; + description = "The port that Pyroscope should run on"; + }; + }; + }; + }; + default = { }; + description = '' + Specify the configuration for Pyroscope in Nix. + + See for available options. + ''; + }; + + configFile = lib.mkOption { + type = lib.types.nullOr lib.types.path; + default = null; + description = "Specify a path to a configuration file that Pyroscope should use."; + }; + + extraFlags = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = [ ]; + description = "Additional arguments to pass to pyroscope"; + }; + }; + + config = lib.mkIf cfg.enable { + + # Pyroscope and it's CLI + environment.systemPackages = [ cfg.package ]; + + assertions = [ + { + assertion = ((cfg.settings == { }) != (cfg.configFile == null)); + message = '' + Please specify a configuration for Pyroscope with either + 'services.pyroscope.settings' or + 'services.pyroscope.configFile'. + ''; + } + ]; + + systemd.services.pyroscope = { + description = "Grafana Pyroscope Service Daemon"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = + let + conf = + if cfg.configFile == null then + settingsFormat.generate "config.yaml" cfg.settings + else + cfg.configFile; + in + { + ExecStart = utils.escapeSystemdExecArgs ( + [ + "${lib.getExe cfg.package}" + "--config.file=${conf}" + ] + ++ cfg.extraFlags + ); + DynamicUser = true; + ProtectSystem = "full"; + DevicePolicy = "closed"; + WorkingDirectory = "/var/lib/pyroscope"; + StateDirectory = "pyroscope"; + Restart = "on-failure"; + }; + }; + + networking.firewall.allowedTCPPorts = lib.mkIf cfg.openFirewall [ + cfg.settings.server.http_listen_port + ]; + + }; + +}