grafana-alloy: don't build the frontend twice
[NixPkgs.git] / nixos / modules / services / logging / filebeat.nix
blob57e0c60735780eb579536ca45d9a77f5effffb36
1 { config, lib, utils, pkgs, ... }:
3 let
4   inherit (lib)
5     attrValues
6     literalExpression
7     mkEnableOption
8     mkPackageOption
9     mkIf
10     mkOption
11     types;
13   cfg = config.services.filebeat;
15   json = pkgs.formats.json {};
18   options = {
20     services.filebeat = {
22       enable = mkEnableOption "filebeat";
24       package = mkPackageOption pkgs "filebeat" {
25         example = "filebeat7";
26       };
28       inputs = mkOption {
29         description = ''
30           Inputs specify how Filebeat locates and processes input data.
32           This is like `services.filebeat.settings.filebeat.inputs`,
33           but structured as an attribute set. This has the benefit
34           that multiple NixOS modules can contribute settings to a
35           single filebeat input.
37           An input type can be specified multiple times by choosing a
38           different `<name>` for each, but setting
39           [](#opt-services.filebeat.inputs._name_.type)
40           to the same value.
42           See <https://www.elastic.co/guide/en/beats/filebeat/current/configuration-filebeat-options.html>.
43         '';
44         default = {};
45         type = types.attrsOf (types.submodule ({ name, ... }: {
46           freeformType = json.type;
47           options = {
48             type = mkOption {
49               type = types.str;
50               default = name;
51               description = ''
52                 The input type.
54                 Look for the value after `type:` on
55                 the individual input pages linked from
56                 <https://www.elastic.co/guide/en/beats/filebeat/current/configuration-filebeat-options.html>.
57               '';
58             };
59           };
60         }));
61         example = literalExpression ''
62           {
63             journald.id = "everything";  # Only for filebeat7
64             log = {
65               enabled = true;
66               paths = [
67                 "/var/log/*.log"
68               ];
69             };
70           };
71         '';
72       };
74       modules = mkOption {
75         description = ''
76           Filebeat modules provide a quick way to get started
77           processing common log formats. They contain default
78           configurations, Elasticsearch ingest pipeline definitions,
79           and Kibana dashboards to help you implement and deploy a log
80           monitoring solution.
82           This is like `services.filebeat.settings.filebeat.modules`,
83           but structured as an attribute set. This has the benefit
84           that multiple NixOS modules can contribute settings to a
85           single filebeat module.
87           A module can be specified multiple times by choosing a
88           different `<name>` for each, but setting
89           [](#opt-services.filebeat.modules._name_.module)
90           to the same value.
92           See <https://www.elastic.co/guide/en/beats/filebeat/current/filebeat-modules.html>.
93         '';
94         default = {};
95         type = types.attrsOf (types.submodule ({ name, ... }: {
96           freeformType = json.type;
97           options = {
98             module = mkOption {
99               type = types.str;
100               default = name;
101               description = ''
102                 The name of the module.
104                 Look for the value after `module:` on
105                 the individual input pages linked from
106                 <https://www.elastic.co/guide/en/beats/filebeat/current/filebeat-modules.html>.
107               '';
108             };
109           };
110         }));
111         example = literalExpression ''
112           {
113             nginx = {
114               access = {
115                 enabled = true;
116                 var.paths = [ "/path/to/log/nginx/access.log*" ];
117               };
118               error = {
119                 enabled = true;
120                 var.paths = [ "/path/to/log/nginx/error.log*" ];
121               };
122             };
123           };
124         '';
125       };
127       settings = mkOption {
128         type = types.submodule {
129           freeformType = json.type;
131           options = {
133             output.elasticsearch.hosts = mkOption {
134               type = with types; listOf str;
135               default = [ "127.0.0.1:9200" ];
136               example = [ "myEShost:9200" ];
137               description = ''
138                 The list of Elasticsearch nodes to connect to.
140                 The events are distributed to these nodes in round
141                 robin order. If one node becomes unreachable, the
142                 event is automatically sent to another node. Each
143                 Elasticsearch node can be defined as a URL or
144                 IP:PORT. For example:
145                 `http://192.15.3.2`,
146                 `https://es.found.io:9230` or
147                 `192.24.3.2:9300`. If no port is
148                 specified, `9200` is used.
149               '';
150             };
152             filebeat = {
153               inputs = mkOption {
154                 type = types.listOf json.type;
155                 default = [];
156                 internal = true;
157                 description = ''
158                   Inputs specify how Filebeat locates and processes
159                   input data. Use [](#opt-services.filebeat.inputs) instead.
161                   See <https://www.elastic.co/guide/en/beats/filebeat/current/configuration-filebeat-options.html>.
162                 '';
163               };
164               modules = mkOption {
165                 type = types.listOf json.type;
166                 default = [];
167                 internal = true;
168                 description = ''
169                   Filebeat modules provide a quick way to get started
170                   processing common log formats. They contain default
171                   configurations, Elasticsearch ingest pipeline
172                   definitions, and Kibana dashboards to help you
173                   implement and deploy a log monitoring solution.
175                   Use [](#opt-services.filebeat.modules) instead.
177                   See <https://www.elastic.co/guide/en/beats/filebeat/current/filebeat-modules.html>.
178                 '';
179               };
180             };
181           };
182         };
183         default = {};
184         example = literalExpression ''
185           {
186             settings = {
187               output.elasticsearch = {
188                 hosts = [ "myEShost:9200" ];
189                 username = "filebeat_internal";
190                 password = { _secret = "/var/keys/elasticsearch_password"; };
191               };
192               logging.level = "info";
193             };
194           };
195         '';
197         description = ''
198           Configuration for filebeat. See
199           <https://www.elastic.co/guide/en/beats/filebeat/current/filebeat-reference-yml.html>
200           for supported values.
202           Options containing secret data should be set to an attribute
203           set containing the attribute `_secret` - a
204           string pointing to a file containing the value the option
205           should be set to. See the example to get a better picture of
206           this: in the resulting
207           {file}`filebeat.yml` file, the
208           `output.elasticsearch.password`
209           key will be set to the contents of the
210           {file}`/var/keys/elasticsearch_password` file.
211         '';
212       };
213     };
214   };
216   config = mkIf cfg.enable {
218     services.filebeat.settings.filebeat.inputs = attrValues cfg.inputs;
219     services.filebeat.settings.filebeat.modules = attrValues cfg.modules;
221     systemd.services.filebeat = {
222       description = "Filebeat log shipper";
223       wantedBy = [ "multi-user.target" ];
224       wants = [ "elasticsearch.service" ];
225       after = [ "elasticsearch.service" ];
226       serviceConfig = {
227         ExecStartPre = pkgs.writeShellScript "filebeat-exec-pre" ''
228           set -euo pipefail
230           umask u=rwx,g=,o=
232           ${utils.genJqSecretsReplacementSnippet
233               cfg.settings
234               "/var/lib/filebeat/filebeat.yml"
235            }
236         '';
237         ExecStart = ''
238           ${cfg.package}/bin/filebeat -e \
239             -c "/var/lib/filebeat/filebeat.yml" \
240             --path.data "/var/lib/filebeat"
241         '';
242         Restart = "always";
243         StateDirectory = "filebeat";
244       };
245     };
246   };