grafana-alloy: don't build the frontend twice
[NixPkgs.git] / nixos / modules / services / logging / logstash.nix
blob31f0eef77c461b84a9d70d80f43c693bee32cf81
1 { config, lib, pkgs, ... }:
2 let
3   cfg = config.services.logstash;
4   ops = lib.optionalString;
5   verbosityFlag = "--log.level " + cfg.logLevel;
7   logstashConf = pkgs.writeText "logstash.conf" ''
8     input {
9       ${cfg.inputConfig}
10     }
12     filter {
13       ${cfg.filterConfig}
14     }
16     output {
17       ${cfg.outputConfig}
18     }
19   '';
21   logstashSettingsYml = pkgs.writeText "logstash.yml" cfg.extraSettings;
23   logstashJvmOptionsFile = pkgs.writeText "jvm.options" cfg.extraJvmOptions;
25   logstashSettingsDir = pkgs.runCommand "logstash-settings" {
26       inherit logstashJvmOptionsFile;
27       inherit logstashSettingsYml;
28       preferLocalBuild = true;
29     } ''
30     mkdir -p $out
31     ln -s $logstashSettingsYml $out/logstash.yml
32     ln -s $logstashJvmOptionsFile $out/jvm.options
33   '';
37   imports = [
38     (lib.mkRenamedOptionModule [ "services" "logstash" "address" ] [ "services" "logstash" "listenAddress" ])
39     (lib.mkRemovedOptionModule [ "services" "logstash" "enableWeb" ] "The web interface was removed from logstash")
40   ];
42   ###### interface
44   options = {
46     services.logstash = {
48       enable = lib.mkOption {
49         type = lib.types.bool;
50         default = false;
51         description = "Enable logstash.";
52       };
54       package = lib.mkPackageOption pkgs "logstash" { };
56       plugins = lib.mkOption {
57         type = lib.types.listOf lib.types.path;
58         default = [ ];
59         example = lib.literalExpression "[ pkgs.logstash-contrib ]";
60         description = "The paths to find other logstash plugins in.";
61       };
63       dataDir = lib.mkOption {
64         type = lib.types.str;
65         default = "/var/lib/logstash";
66         description = ''
67           A path to directory writable by logstash that it uses to store data.
68           Plugins will also have access to this path.
69         '';
70       };
72       logLevel = lib.mkOption {
73         type = lib.types.enum [ "debug" "info" "warn" "error" "fatal" ];
74         default = "warn";
75         description = "Logging verbosity level.";
76       };
78       filterWorkers = lib.mkOption {
79         type = lib.types.int;
80         default = 1;
81         description = "The quantity of filter workers to run.";
82       };
84       listenAddress = lib.mkOption {
85         type = lib.types.str;
86         default = "127.0.0.1";
87         description = "Address on which to start webserver.";
88       };
90       port = lib.mkOption {
91         type = lib.types.str;
92         default = "9292";
93         description = "Port on which to start webserver.";
94       };
96       inputConfig = lib.mkOption {
97         type = lib.types.lines;
98         default = "generator { }";
99         description = "Logstash input configuration.";
100         example = lib.literalExpression ''
101           '''
102             # Read from journal
103             pipe {
104               command => "''${config.systemd.package}/bin/journalctl -f -o json"
105               type => "syslog" codec => json {}
106             }
107           '''
108         '';
109       };
111       filterConfig = lib.mkOption {
112         type = lib.types.lines;
113         default = "";
114         description = "logstash filter configuration.";
115         example = ''
116           if [type] == "syslog" {
117             # Keep only relevant systemd fields
118             # https://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html
119             prune {
120               whitelist_names => [
121                 "type", "@timestamp", "@version",
122                 "MESSAGE", "PRIORITY", "SYSLOG_FACILITY"
123               ]
124             }
125           }
126         '';
127       };
129       outputConfig = lib.mkOption {
130         type = lib.types.lines;
131         default = "stdout { codec => rubydebug }";
132         description = "Logstash output configuration.";
133         example = ''
134           redis { host => ["localhost"] data_type => "list" key => "logstash" codec => json }
135           elasticsearch { }
136         '';
137       };
139       extraSettings = lib.mkOption {
140         type = lib.types.lines;
141         default = "";
142         description = "Extra Logstash settings in YAML format.";
143         example = ''
144           pipeline:
145             batch:
146               size: 125
147               delay: 5
148         '';
149       };
151       extraJvmOptions = lib.mkOption {
152         type = lib.types.lines;
153         default = "";
154         description = "Extra JVM options, one per line (jvm.options format).";
155         example = ''
156           -Xms2g
157           -Xmx2g
158         '';
159       };
161     };
162   };
165   ###### implementation
167   config = lib.mkIf cfg.enable {
168     systemd.services.logstash = {
169       description = "Logstash Daemon";
170       wantedBy = [ "multi-user.target" ];
171       path = [ pkgs.bash ];
172       serviceConfig = {
173         ExecStartPre = ''${pkgs.coreutils}/bin/mkdir -p "${cfg.dataDir}" ; ${pkgs.coreutils}/bin/chmod 700 "${cfg.dataDir}"'';
174         ExecStart = lib.concatStringsSep " " (lib.filter (s: lib.stringLength s != 0) [
175           "${cfg.package}/bin/logstash"
176           "-w ${toString cfg.filterWorkers}"
177           (lib.concatMapStringsSep " " (x: "--path.plugins ${x}") cfg.plugins)
178           "${verbosityFlag}"
179           "-f ${logstashConf}"
180           "--path.settings ${logstashSettingsDir}"
181           "--path.data ${cfg.dataDir}"
182         ]);
183       };
184     };
185   };