Nix Observability Daemon
observability nix
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

cleanup flake.nix

+111 -67
+111 -66
flake.nix
··· 7 7 rust-overlay.inputs.nixpkgs.follows = "nixpkgs"; 8 8 }; 9 9 10 - outputs = { self, nixpkgs, rust-overlay }: 11 - let 12 - systems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ]; 13 - forAllSystems = f: nixpkgs.lib.genAttrs systems (system: f (import nixpkgs { 14 - inherit system; 15 - overlays = [ (import rust-overlay) ]; 16 - })); 17 - in 18 - { 19 - packages = forAllSystems (pkgs: { 20 - default = pkgs.rustPlatform.buildRustPackage { 21 - pname = "nod"; 22 - version = "0.1.0"; 23 - src = ./.; 24 - cargoLock.lockFile = ./Cargo.lock; 10 + outputs = { 11 + self, 12 + nixpkgs, 13 + rust-overlay, 14 + }: let 15 + systems = ["x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin"]; 16 + forAllSystems = f: 17 + nixpkgs.lib.genAttrs systems (system: 18 + f (import nixpkgs { 19 + inherit system; 20 + overlays = [(import rust-overlay)]; 21 + })); 22 + in { 23 + packages = forAllSystems (pkgs: { 24 + default = pkgs.rustPlatform.buildRustPackage { 25 + pname = "nod"; 26 + version = "0.1.0"; 27 + src = ./.; 28 + cargoLock.lockFile = ./Cargo.lock; 25 29 26 - nativeBuildInputs = [ pkgs.pkg-config ]; 27 - buildInputs = [ pkgs.sqlite ] 28 - ++ (if pkgs.stdenv.isDarwin then [ pkgs.iconv ] else []); 29 - 30 - # Ensures SQLx doesn't try to connect to a DB during the build 31 - SQLX_OFFLINE = "true"; 32 - }; 33 - }); 34 - devShells = forAllSystems (pkgs: { 35 - default = pkgs.mkShell { 36 - buildInputs = [ 30 + nativeBuildInputs = [pkgs.pkg-config]; 31 + buildInputs = 32 + [pkgs.sqlite] 33 + ++ ( 34 + if pkgs.stdenv.isDarwin 35 + then [pkgs.iconv] 36 + else [] 37 + ); 38 + }; 39 + }); 40 + devShells = forAllSystems (pkgs: { 41 + default = pkgs.mkShell { 42 + buildInputs = 43 + [ 37 44 pkgs.rust-bin.stable.latest.default 38 45 pkgs.pkg-config 39 46 pkgs.sqlite 40 - pkgs.sqlx-cli 41 - ] ++ (if pkgs.stdenv.isDarwin then [ pkgs.iconv ] else []); 47 + ] 48 + ++ ( 49 + if pkgs.stdenv.isDarwin 50 + then [pkgs.iconv] 51 + else [] 52 + ); 53 + }; 54 + }); 55 + 56 + nixosModules.default = { 57 + config, 58 + lib, 59 + pkgs, 60 + ... 61 + }: let 62 + cfg = config.services.nod; 63 + in { 64 + options.services.nod = { 65 + enable = lib.mkEnableOption "Nix Observability Daemon"; 66 + package = lib.mkOption { 67 + type = lib.types.package; 68 + default = self.packages.${pkgs.system}.default; 69 + description = "The nod package to use."; 70 + }; 71 + user = lib.mkOption { 72 + type = lib.types.str; 73 + default = "nod"; 74 + description = "User to run the nod daemon as."; 75 + }; 76 + group = lib.mkOption { 77 + type = lib.types.str; 78 + default = "nod"; 79 + description = '' 80 + Group for the nod daemon. Other services that need read access to the database (e.g. a monitoring agent) should be added to this group. 81 + ''; 42 82 }; 43 - }); 44 83 45 - nixosModules.default = { config, lib, pkgs, ... }: 46 - let 47 - cfg = config.services.nod; 48 - in { 49 - options.services.nod = { 50 - enable = lib.mkEnableOption "Nix Observability Daemon"; 51 - package = lib.mkOption { 52 - type = lib.types.package; 53 - default = self.packages.${pkgs.system}.default; 54 - }; 55 - socketPath = lib.mkOption { 56 - type = lib.types.path; 57 - default = "/run/nod/nod.sock"; 58 - }; 59 - databasePath = lib.mkOption { 60 - type = lib.types.path; 61 - default = "/var/lib/nod/nod.db"; 62 - }; 63 - }; 84 + socketPath = lib.mkOption { 85 + type = lib.types.path; 86 + default = "/run/nod/nod.sock"; 87 + description = "Path to the Unix socket. Exposed via NOD_SOCKET in the session environment."; 88 + }; 89 + databasePath = lib.mkOption { 90 + type = lib.types.path; 91 + default = "/var/lib/nod/nod.db"; 92 + description = "Path to the SQLite database"; 93 + }; 94 + }; 64 95 65 - config = lib.mkIf cfg.enable { 66 - nix.settings.json-log-path = cfg.socketPath; 96 + config = lib.mkIf cfg.enable { 97 + users.users.${cfg.user} = { 98 + isSystemUser = true; 99 + group = cfg.group; 100 + description = "Nix Observability Daemon"; 101 + }; 102 + users.groups.${cfg.group} = {}; 67 103 68 - environment.sessionVariables.NOD_SOCKET = cfg.socketPath; 104 + # Tell nix to forward its internal JSON log to the socket 105 + nix.settings.json-log-path = cfg.socketPath; 69 106 70 - systemd.services.nod = { 71 - description = "Nix Observability Daemon"; 72 - wantedBy = [ "multi-user.target" ]; 73 - after = [ "network.target" ]; 74 - 75 - serviceConfig = { 76 - ExecStart = "${cfg.package}/bin/nod daemon --db-url sqlite:${cfg.databasePath} --socket ${cfg.socketPath}"; 77 - Restart = "always"; 78 - DynamicUser = true; 79 - StateDirectory = "nod"; # Creates /var/lib/nod 80 - RuntimeDirectory = "nod"; # Creates /run/nod 81 - RuntimeDirectoryMode = "0755"; # Allows others to enter the directory 82 - UMask = "0000"; # Allows the socket itself to be world-writable 83 - }; 84 - }; 107 + # Make the socket path available to interactive shells so users 108 + # can run `nod stats` without passing --socket explicitly. 109 + environment.sessionVariables.NOD_SOCKET = cfg.socketPath; 110 + 111 + systemd.services.nod = { 112 + description = "Nix Observability Daemon"; 113 + wantedBy = ["multi-user.target"]; 114 + after = ["network.target"]; 115 + 116 + serviceConfig = { 117 + User = cfg.user; 118 + Group = cfg.group; 119 + ExecStart = "${cfg.package}/bin/nod daemon --db ${cfg.databasePath} --socket ${cfg.socketPath}"; 120 + Restart = "always"; 121 + StateDirectory = "nod"; 122 + StateDirectoryMode = "0750"; 123 + # /run/nod must be world-searchable so nix (running as any user) can reach the socket. 124 + RuntimeDirectory = "nod"; 125 + RuntimeDirectoryMode = "0755"; 126 + # SQLite WAL mode requires write access to the -shm file even for read-only connections. 127 + UMask = "0117"; 85 128 }; 86 129 }; 130 + }; 87 131 }; 132 + }; 88 133 }
-1
src/daemon.rs
··· 209 209 conn.execute_batch(" 210 210 PRAGMA journal_mode = WAL; 211 211 PRAGMA synchronous = NORMAL; 212 - PRAGMA locking_mode = EXCLUSIVE; 213 212 PRAGMA temp_store = MEMORY; 214 213 PRAGMA mmap_size = 134217728; 215 214 PRAGMA cache_size = -8000;