at 25.11-pre 3.8 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7let 8 9 cfg = config.services.statsd; 10 11 isBuiltinBackend = 12 name: 13 builtins.elem name [ 14 "graphite" 15 "console" 16 "repeater" 17 ]; 18 19 backendsToPackages = 20 let 21 mkMap = list: name: if isBuiltinBackend name then list else list ++ [ pkgs.nodePackages.${name} ]; 22 in 23 lib.foldl mkMap [ ]; 24 25 configFile = pkgs.writeText "statsd.conf" '' 26 { 27 address: "${cfg.listenAddress}", 28 port: "${toString cfg.port}", 29 mgmt_address: "${cfg.mgmt_address}", 30 mgmt_port: "${toString cfg.mgmt_port}", 31 backends: [${ 32 lib.concatMapStringsSep "," ( 33 name: if (isBuiltinBackend name) then ''"./backends/${name}"'' else ''"${name}"'' 34 ) cfg.backends 35 }], 36 ${lib.optionalString (cfg.graphiteHost != null) ''graphiteHost: "${cfg.graphiteHost}",''} 37 ${lib.optionalString (cfg.graphitePort != null) ''graphitePort: "${toString cfg.graphitePort}",''} 38 console: { 39 prettyprint: false 40 }, 41 log: { 42 backend: "stdout" 43 }, 44 automaticConfigReload: false${lib.optionalString (cfg.extraConfig != null) ","} 45 ${cfg.extraConfig} 46 } 47 ''; 48 49 deps = pkgs.buildEnv { 50 name = "statsd-runtime-deps"; 51 pathsToLink = [ "/lib" ]; 52 ignoreCollisions = true; 53 54 paths = backendsToPackages cfg.backends; 55 }; 56 57in 58 59{ 60 61 ###### interface 62 63 options.services.statsd = { 64 65 enable = lib.mkEnableOption "statsd"; 66 67 listenAddress = lib.mkOption { 68 description = "Address that statsd listens on over UDP"; 69 default = "127.0.0.1"; 70 type = lib.types.str; 71 }; 72 73 port = lib.mkOption { 74 description = "Port that stats listens for messages on over UDP"; 75 default = 8125; 76 type = lib.types.int; 77 }; 78 79 mgmt_address = lib.mkOption { 80 description = "Address to run management TCP interface on"; 81 default = "127.0.0.1"; 82 type = lib.types.str; 83 }; 84 85 mgmt_port = lib.mkOption { 86 description = "Port to run the management TCP interface on"; 87 default = 8126; 88 type = lib.types.int; 89 }; 90 91 backends = lib.mkOption { 92 description = "List of backends statsd will use for data persistence"; 93 default = [ ]; 94 example = [ 95 "graphite" 96 "console" 97 "repeater" 98 "statsd-librato-backend" 99 "statsd-influxdb-backend" 100 ]; 101 type = lib.types.listOf lib.types.str; 102 }; 103 104 graphiteHost = lib.mkOption { 105 description = "Hostname or IP of Graphite server"; 106 default = null; 107 type = lib.types.nullOr lib.types.str; 108 }; 109 110 graphitePort = lib.mkOption { 111 description = "Port of Graphite server (i.e. carbon-cache)."; 112 default = null; 113 type = lib.types.nullOr lib.types.int; 114 }; 115 116 extraConfig = lib.mkOption { 117 description = "Extra configuration options for statsd"; 118 default = ""; 119 type = lib.types.nullOr lib.types.str; 120 }; 121 122 }; 123 124 ###### implementation 125 126 config = lib.mkIf cfg.enable { 127 128 assertions = map (backend: { 129 assertion = !isBuiltinBackend backend -> lib.hasAttrByPath [ backend ] pkgs.nodePackages; 130 message = "Only builtin backends (graphite, console, repeater) or backends enumerated in `pkgs.nodePackages` are allowed!"; 131 }) cfg.backends; 132 133 users.users.statsd = { 134 uid = config.ids.uids.statsd; 135 description = "Statsd daemon user"; 136 }; 137 138 systemd.services.statsd = { 139 description = "Statsd Server"; 140 wantedBy = [ "multi-user.target" ]; 141 environment = { 142 NODE_PATH = "${deps}/lib/node_modules"; 143 }; 144 serviceConfig = { 145 ExecStart = "${pkgs.statsd}/bin/statsd ${configFile}"; 146 User = "statsd"; 147 }; 148 }; 149 150 environment.systemPackages = [ pkgs.statsd ]; 151 152 }; 153 154}