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