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