at 21.11-pre 9.3 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 cfg = config.services.datadog-agent; 7 8 ddConf = { 9 skip_ssl_validation = false; 10 confd_path = "/etc/datadog-agent/conf.d"; 11 additional_checksd = "/etc/datadog-agent/checks.d"; 12 use_dogstatsd = true; 13 } 14 // optionalAttrs (cfg.logLevel != null) { log_level = cfg.logLevel; } 15 // optionalAttrs (cfg.hostname != null) { inherit (cfg) hostname; } 16 // optionalAttrs (cfg.ddUrl != null) { dd_url = cfg.ddUrl; } 17 // optionalAttrs (cfg.site != null) { site = cfg.site; } 18 // optionalAttrs (cfg.tags != null ) { tags = concatStringsSep ", " cfg.tags; } 19 // optionalAttrs (cfg.enableLiveProcessCollection) { process_config = { enabled = "true"; }; } 20 // optionalAttrs (cfg.enableTraceAgent) { apm_config = { enabled = true; }; } 21 // cfg.extraConfig; 22 23 # Generate Datadog configuration files for each configured checks. 24 # This works because check configurations have predictable paths, 25 # and because JSON is a valid subset of YAML. 26 makeCheckConfigs = entries: mapAttrs' (name: conf: { 27 name = "datadog-agent/conf.d/${name}.d/conf.yaml"; 28 value.source = pkgs.writeText "${name}-check-conf.yaml" (builtins.toJSON conf); 29 }) entries; 30 31 defaultChecks = { 32 disk = cfg.diskCheck; 33 network = cfg.networkCheck; 34 }; 35 36 # Assemble all check configurations and the top-level agent 37 # configuration. 38 etcfiles = with pkgs; with builtins; 39 { "datadog-agent/datadog.yaml" = { 40 source = writeText "datadog.yaml" (toJSON ddConf); 41 }; 42 } // makeCheckConfigs (cfg.checks // defaultChecks); 43 44 # Apply the configured extraIntegrations to the provided agent 45 # package. See the documentation of `dd-agent/integrations-core.nix` 46 # for detailed information on this. 47 datadogPkg = cfg.package.override { 48 pythonPackages = pkgs.datadog-integrations-core cfg.extraIntegrations; 49 }; 50in { 51 options.services.datadog-agent = { 52 enable = mkOption { 53 description = '' 54 Whether to enable the datadog-agent v6 monitoring service 55 ''; 56 default = false; 57 type = types.bool; 58 }; 59 60 package = mkOption { 61 default = pkgs.datadog-agent; 62 defaultText = "pkgs.datadog-agent"; 63 description = '' 64 Which DataDog v6 agent package to use. Note that the provided 65 package is expected to have an overridable `pythonPackages`-attribute 66 which configures the Python environment with the Datadog 67 checks. 68 ''; 69 type = types.package; 70 }; 71 72 apiKeyFile = mkOption { 73 description = '' 74 Path to a file containing the Datadog API key to associate the 75 agent with your account. 76 ''; 77 example = "/run/keys/datadog_api_key"; 78 type = types.path; 79 }; 80 81 ddUrl = mkOption { 82 description = '' 83 Custom dd_url to configure the agent with. Useful if traffic to datadog 84 needs to go through a proxy. 85 Don't use this to point to another datadog site (EU) - use site instead. 86 ''; 87 default = null; 88 example = "http://haproxy.example.com:3834"; 89 type = types.nullOr types.str; 90 }; 91 92 site = mkOption { 93 description = '' 94 The datadog site to point the agent towards. 95 Set to datadoghq.eu to point it to their EU site. 96 ''; 97 default = null; 98 example = "datadoghq.eu"; 99 type = types.nullOr types.str; 100 }; 101 102 tags = mkOption { 103 description = "The tags to mark this Datadog agent"; 104 example = [ "test" "service" ]; 105 default = null; 106 type = types.nullOr (types.listOf types.str); 107 }; 108 109 hostname = mkOption { 110 description = "The hostname to show in the Datadog dashboard (optional)"; 111 default = null; 112 example = "mymachine.mydomain"; 113 type = types.nullOr types.str; 114 }; 115 116 logLevel = mkOption { 117 description = "Logging verbosity."; 118 default = null; 119 type = types.nullOr (types.enum ["DEBUG" "INFO" "WARN" "ERROR"]); 120 }; 121 122 extraIntegrations = mkOption { 123 default = {}; 124 type = types.attrs; 125 126 description = '' 127 Extra integrations from the Datadog core-integrations 128 repository that should be built and included. 129 130 By default the included integrations are disk, mongo, network, 131 nginx and postgres. 132 133 To include additional integrations the name of the derivation 134 and a function to filter its dependencies from the Python 135 package set must be provided. 136 ''; 137 138 example = { 139 ntp = (pythonPackages: [ pythonPackages.ntplib ]); 140 }; 141 }; 142 143 extraConfig = mkOption { 144 default = {}; 145 type = types.attrs; 146 description = '' 147 Extra configuration options that will be merged into the 148 main config file <filename>datadog.yaml</filename>. 149 ''; 150 }; 151 152 enableLiveProcessCollection = mkOption { 153 description = '' 154 Whether to enable the live process collection agent. 155 ''; 156 default = false; 157 type = types.bool; 158 }; 159 160 enableTraceAgent = mkOption { 161 description = '' 162 Whether to enable the trace agent. 163 ''; 164 default = false; 165 type = types.bool; 166 }; 167 168 checks = mkOption { 169 description = '' 170 Configuration for all Datadog checks. Keys of this attribute 171 set will be used as the name of the check to create the 172 appropriate configuration in `conf.d/$check.d/conf.yaml`. 173 174 The configuration is converted into JSON from the plain Nix 175 language configuration, meaning that you should write 176 configuration adhering to Datadog's documentation - but in Nix 177 language. 178 179 Refer to the implementation of this module (specifically the 180 definition of `defaultChecks`) for an example. 181 182 Note: The 'disk' and 'network' check are configured in 183 separate options because they exist by default. Attempting to 184 override their configuration here will have no effect. 185 ''; 186 187 example = { 188 http_check = { 189 init_config = null; # sic! 190 instances = [ 191 { 192 name = "some-service"; 193 url = "http://localhost:1337/healthz"; 194 tags = [ "some-service" ]; 195 } 196 ]; 197 }; 198 }; 199 200 default = {}; 201 202 # sic! The structure of the values is up to the check, so we can 203 # not usefully constrain the type further. 204 type = with types; attrsOf attrs; 205 }; 206 207 diskCheck = mkOption { 208 description = "Disk check config"; 209 type = types.attrs; 210 default = { 211 init_config = {}; 212 instances = [ { use_mount = "false"; } ]; 213 }; 214 }; 215 216 networkCheck = mkOption { 217 description = "Network check config"; 218 type = types.attrs; 219 default = { 220 init_config = {}; 221 # Network check only supports one configured instance 222 instances = [ { collect_connection_state = false; 223 excluded_interfaces = [ "lo" "lo0" ]; } ]; 224 }; 225 }; 226 }; 227 config = mkIf cfg.enable { 228 environment.systemPackages = [ datadogPkg pkgs.sysstat pkgs.procps pkgs.iproute2 ]; 229 230 users.users.datadog = { 231 description = "Datadog Agent User"; 232 uid = config.ids.uids.datadog; 233 group = "datadog"; 234 home = "/var/log/datadog/"; 235 createHome = true; 236 }; 237 238 users.groups.datadog.gid = config.ids.gids.datadog; 239 240 systemd.services = let 241 makeService = attrs: recursiveUpdate { 242 path = [ datadogPkg pkgs.python pkgs.sysstat pkgs.procps pkgs.iproute2 ]; 243 wantedBy = [ "multi-user.target" ]; 244 serviceConfig = { 245 User = "datadog"; 246 Group = "datadog"; 247 Restart = "always"; 248 RestartSec = 2; 249 }; 250 restartTriggers = [ datadogPkg ] ++ map (x: x.source) (attrValues etcfiles); 251 } attrs; 252 in { 253 datadog-agent = makeService { 254 description = "Datadog agent monitor"; 255 preStart = '' 256 chown -R datadog: /etc/datadog-agent 257 rm -f /etc/datadog-agent/auth_token 258 ''; 259 script = '' 260 export DD_API_KEY=$(head -n 1 ${cfg.apiKeyFile}) 261 exec ${datadogPkg}/bin/agent run -c /etc/datadog-agent/datadog.yaml 262 ''; 263 serviceConfig.PermissionsStartOnly = true; 264 }; 265 266 dd-jmxfetch = lib.mkIf (lib.hasAttr "jmx" cfg.checks) (makeService { 267 description = "Datadog JMX Fetcher"; 268 path = [ datadogPkg pkgs.python pkgs.sysstat pkgs.procps pkgs.jdk ]; 269 serviceConfig.ExecStart = "${datadogPkg}/bin/dd-jmxfetch"; 270 }); 271 272 datadog-process-agent = lib.mkIf cfg.enableLiveProcessCollection (makeService { 273 description = "Datadog Live Process Agent"; 274 path = [ ]; 275 script = '' 276 export DD_API_KEY=$(head -n 1 ${cfg.apiKeyFile}) 277 ${pkgs.datadog-process-agent}/bin/agent --config /etc/datadog-agent/datadog.yaml 278 ''; 279 }); 280 281 datadog-trace-agent = lib.mkIf cfg.enableTraceAgent (makeService { 282 description = "Datadog Trace Agent"; 283 path = [ ]; 284 script = '' 285 export DD_API_KEY=$(head -n 1 ${cfg.apiKeyFile}) 286 ${datadogPkg}/bin/trace-agent -config /etc/datadog-agent/datadog.yaml 287 ''; 288 }); 289 290 }; 291 292 environment.etc = etcfiles; 293 }; 294}