{ config, pkgs, lib, ... }: with lib; let cfg = config.services.naxos.perses; # Declarative Perses Prometheus Datasource Manifest datasourceManifest = pkgs.writeText "perses-prom-datasource.json" (builtins.toJSON { kind = "Datasource"; metadata = { name = "PrometheusDemo"; project = "naxos"; }; spec = { default = true; plugin = { kind = "PrometheusDatasource"; spec = { directUrl = "http://127.0.0.1:9090"; }; }; }; }); # Declarative Perses ZFS & System Dashboard Manifest zfsDashboardManifest = pkgs.writeText "perses-zfs-dashboard.json" (builtins.toJSON { kind = "Dashboard"; metadata = { name = "zfs-storage-health"; project = "naxos"; }; spec = { duration = "1h"; refreshInterval = "10s"; display = { name = "ZFS Storage & System Health"; description = "Native NaxOS analytics powered by Perses"; }; variables = []; panels = { cpuUsage = { kind = "Panel"; spec = { display = { name = "CPU Utilization (%)"; }; plugin = { kind = "TimeSeriesChart"; spec = { queries = [{ kind = "TimeSeriesQuery"; spec = { plugin = { kind = "PrometheusTimeSeriesQuery"; spec = { query = "100 - (avg by (instance) (rate(node_cpu_seconds_total{mode='idle'}[1m])) * 100)"; }; }; }; }]; }; }; }; }; memoryArc = { kind = "Panel"; spec = { display = { name = "Memory & ARC Cache (Bytes)"; }; plugin = { kind = "TimeSeriesChart"; spec = { queries = [ { kind = "TimeSeriesQuery"; spec = { plugin = { kind = "PrometheusTimeSeriesQuery"; spec = { query = "node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes"; }; }; }; } ]; }; }; }; }; diskIO = { kind = "Panel"; spec = { display = { name = "ZFS Pool Read/Write Throughput"; }; plugin = { kind = "TimeSeriesChart"; spec = { queries = [{ kind = "TimeSeriesQuery"; spec = { plugin = { kind = "PrometheusTimeSeriesQuery"; spec = { query = "rate(node_disk_read_bytes_total[1m]) + rate(node_disk_written_bytes_total[1m])"; }; }; }; }]; }; }; }; }; }; layouts = [ { kind = "Grid"; spec = { items = [ { x = 0; y = 0; width = 12; height = 6; content = { "$ref" = "#/spec/panels/cpuUsage"; }; } { x = 12; y = 0; width = 12; height = 6; content = { "$ref" = "#/spec/panels/memoryArc"; }; } { x = 0; y = 6; width = 24; height = 8; content = { "$ref" = "#/spec/panels/diskIO"; }; } ]; }; } ]; }; }); persesConfigFile = pkgs.writeText "perses-config.yaml" '' database: file: folder: "/var/lib/perses" extension: "json" schemas: panels_path: "/var/lib/perses/schemas/panels" queries_path: "/var/lib/perses/schemas/queries" datasources_path: "/var/lib/perses/schemas/datasources" variables_path: "/var/lib/perses/schemas/variables" security: readonly: false enable_auth: false ''; in { options.services.naxos.perses = { enable = mkEnableOption "Perses Embedded Analytics Engine"; port = mkOption { type = types.port; default = 8080; description = "Perses dashboard server port."; }; }; config = mkIf cfg.enable { # System user for Perses users.users.perses = { isSystemUser = true; group = "perses"; home = "/var/lib/perses"; createHome = true; }; users.groups.perses = {}; # Systemd service for Perses systemd.services.perses = { description = "Perses Native Observability and Dashboard Service"; wantedBy = [ "multi-user.target" ]; after = [ "network.target" "prometheus.service" ]; serviceConfig = { User = "perses"; Group = "perses"; StateDirectory = "perses"; WorkingDirectory = "/var/lib/perses"; ExecStartPre = pkgs.writeShellScript "perses-provisioning" '' mkdir -p /var/lib/perses/projects/naxos/dashboards mkdir -p /var/lib/perses/projects/naxos/datasources cp -f ${datasourceManifest} /var/lib/perses/projects/naxos/datasources/PrometheusDemo.json cp -f ${zfsDashboardManifest} /var/lib/perses/projects/naxos/dashboards/zfs-storage-health.json ''; ExecStart = "${pkgs.perses or pkgs.prometheus}/bin/perses --config=${persesConfigFile} --port=${toString cfg.port}"; Restart = "always"; RestartSec = "5s"; }; }; networking.firewall.allowedTCPPorts = [ cfg.port ]; }; }