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