at 25.11-pre 3.9 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7let 8 cfg = config.services.below; 9 cfgContents = lib.concatStringsSep "\n" ( 10 lib.mapAttrsToList (n: v: ''${n} = "${v}"'') ( 11 lib.filterAttrs (_k: v: v != null) { 12 log_dir = cfg.dirs.log; 13 store_dir = cfg.dirs.store; 14 cgroup_filter_out = cfg.cgroupFilterOut; 15 } 16 ) 17 ); 18 19 mkDisableOption = 20 n: 21 lib.mkOption { 22 type = lib.types.bool; 23 default = true; 24 description = "Whether to enable ${n}."; 25 }; 26 optionalType = 27 ty: x: 28 lib.mkOption ( 29 x 30 // { 31 description = x.description; 32 type = (lib.types.nullOr ty); 33 default = null; 34 } 35 ); 36 optionalPath = optionalType lib.types.path; 37 optionalStr = optionalType lib.types.str; 38 optionalInt = optionalType lib.types.int; 39in 40{ 41 options = { 42 services.below = { 43 enable = lib.mkEnableOption "'below' resource monitor"; 44 45 cgroupFilterOut = optionalStr { 46 description = "A regexp matching the full paths of cgroups whose data shouldn't be collected"; 47 example = "user.slice.*"; 48 }; 49 collect = { 50 diskStats = mkDisableOption "dist_stat collection"; 51 ioStats = lib.mkEnableOption "io.stat collection for cgroups"; 52 exitStats = mkDisableOption "eBPF-based exitstats"; 53 }; 54 compression.enable = lib.mkEnableOption "data compression"; 55 retention = { 56 size = optionalInt { 57 description = '' 58 Size limit for below's data, in bytes. Data is deleted oldest-first, in 24h 'shards'. 59 60 ::: {.note} 61 The size limit may be exceeded by at most the size of the active shard, as: 62 - the active shard cannot be deleted; 63 - the size limit is only enforced when a new shard is created. 64 ::: 65 ''; 66 }; 67 time = optionalInt { 68 description = '' 69 Retention time, in seconds. 70 71 ::: {.note} 72 As data is stored in 24 hour shards which are discarded as a whole, 73 only data expired by 24h (or more) is guaranteed to be discarded. 74 ::: 75 76 ::: {.note} 77 If `retention.size` is set, data may be discarded earlier than the specified time. 78 ::: 79 ''; 80 }; 81 }; 82 dirs = { 83 log = optionalPath { description = "Where to store below's logs"; }; 84 store = optionalPath { 85 description = "Where to store below's data"; 86 example = "/var/lib/below"; 87 }; 88 }; 89 }; 90 }; 91 92 config = lib.mkIf cfg.enable { 93 environment.systemPackages = [ pkgs.below ]; 94 # /etc/below.conf is also refered to by the `below` CLI tool, 95 # so this can't be a store-only file whose path is passed to the service 96 environment.etc."below/below.conf".text = cfgContents; 97 98 systemd = { 99 packages = [ pkgs.below ]; 100 services.below = { 101 # Workaround for https://github.com/NixOS/nixpkgs/issues/81138 102 wantedBy = [ "multi-user.target" ]; 103 restartTriggers = [ cfgContents ]; 104 105 serviceConfig.ExecStart = [ 106 "" 107 ( 108 "${lib.getExe pkgs.below} record " 109 + (lib.concatStringsSep " " ( 110 lib.optional (!cfg.collect.diskStats) "--disable-disk-stat" 111 ++ lib.optional cfg.collect.ioStats "--collect-io-stat" 112 ++ lib.optional (!cfg.collect.exitStats) "--disable-exitstats" 113 ++ lib.optional cfg.compression.enable "--compress" 114 ++ 115 116 lib.optional (cfg.retention.size != null) "--store-size-limit ${toString cfg.retention.size}" 117 ++ lib.optional (cfg.retention.time != null) "--retain-for-s ${toString cfg.retention.time}" 118 )) 119 ) 120 ]; 121 }; 122 }; 123 }; 124 125 meta.maintainers = with lib.maintainers; [ nicoo ]; 126}