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