1{ config, lib, pkgs, ... }:
2
3let
4 inherit (lib)
5 attrValues
6 literalExpression
7 mkEnableOption
8 mkPackageOption
9 mkIf
10 mkOption
11 types
12 ;
13 cfg = config.services.metricbeat;
14
15 settingsFormat = pkgs.formats.yaml {};
16
17in
18{
19 options = {
20
21 services.metricbeat = {
22
23 enable = mkEnableOption "metricbeat";
24
25 package = mkPackageOption pkgs "metricbeat" {
26 example = "metricbeat7";
27 };
28
29 modules = mkOption {
30 description = ''
31 Metricbeat modules are responsible for reading metrics from the various sources.
32
33 This is like `services.metricbeat.settings.metricbeat.modules`,
34 but structured as an attribute set. This has the benefit that multiple
35 NixOS modules can contribute settings to a single metricbeat module.
36
37 A module can be specified multiple times by choosing a different `<name>`
38 for each, but setting [](#opt-services.metricbeat.modules._name_.module) to the same value.
39
40 See <https://www.elastic.co/guide/en/beats/metricbeat/current/metricbeat-modules.html>.
41 '';
42 default = {};
43 type = types.attrsOf (types.submodule ({ name, ... }: {
44 freeformType = settingsFormat.type;
45 options = {
46 module = mkOption {
47 type = types.str;
48 default = name;
49 description = ''
50 The name of the module.
51
52 Look for the value after `module:` on the individual
53 module pages linked from <https://www.elastic.co/guide/en/beats/metricbeat/current/metricbeat-modules.html>.
54 '';
55 };
56 };
57 }));
58 example = {
59 system = {
60 metricsets = ["cpu" "load" "memory" "network" "process" "process_summary" "uptime" "socket_summary"];
61 enabled = true;
62 period = "10s";
63 processes = [".*"];
64 cpu.metrics = ["percentages" "normalized_percentages"];
65 core.metrics = ["percentages"];
66 };
67 };
68 };
69
70 settings = mkOption {
71 type = types.submodule {
72 freeformType = settingsFormat.type;
73 options = {
74
75 name = mkOption {
76 type = types.str;
77 default = "";
78 description = ''
79 Name of the beat. Defaults to the hostname.
80 See <https://www.elastic.co/guide/en/beats/metricbeat/current/configuration-general-options.html#_name>.
81 '';
82 };
83
84 tags = mkOption {
85 type = types.listOf types.str;
86 default = [];
87 description = ''
88 Tags to place on the shipped metrics.
89 See <https://www.elastic.co/guide/en/beats/metricbeat/current/configuration-general-options.html#_tags_2>.
90 '';
91 };
92
93 metricbeat.modules = mkOption {
94 type = types.listOf settingsFormat.type;
95 default = [];
96 internal = true;
97 description = ''
98 The metric collecting modules. Use [](#opt-services.metricbeat.modules) instead.
99
100 See <https://www.elastic.co/guide/en/beats/metricbeat/current/metricbeat-modules.html>.
101 '';
102 };
103 };
104 };
105 default = {};
106 description = ''
107 Configuration for metricbeat. See <https://www.elastic.co/guide/en/beats/metricbeat/current/configuring-howto-metricbeat.html> for supported values.
108 '';
109 };
110
111 };
112 };
113
114 config = mkIf cfg.enable {
115
116 assertions = [
117 {
118 # empty modules would cause a failure at runtime
119 assertion = cfg.settings.metricbeat.modules != [];
120 message = "services.metricbeat: You must configure one or more modules.";
121 }
122 ];
123
124 services.metricbeat.settings.metricbeat.modules = attrValues cfg.modules;
125
126 systemd.services.metricbeat = {
127 description = "metricbeat metrics shipper";
128 wantedBy = [ "multi-user.target" ];
129 serviceConfig = {
130 ExecStart = ''
131 ${cfg.package}/bin/metricbeat \
132 -c ${settingsFormat.generate "metricbeat.yml" cfg.settings} \
133 --path.data $STATE_DIRECTORY \
134 --path.logs $LOGS_DIRECTORY \
135 ;
136 '';
137 Restart = "always";
138 DynamicUser = true;
139 ProtectSystem = "strict";
140 ProtectHome = "tmpfs";
141 StateDirectory = "metricbeat";
142 LogsDirectory = "metricbeat";
143 };
144 };
145 };
146}