python3Packages.orjson: Disable failing tests on 32 bit
[NixPkgs.git] / nixos / modules / services / logging / logcheck.nix
blob8a277cea6e461bc4c61a7f054dcb32f598ccb1b9
1 { config, lib, pkgs, ... }:
3 with lib;
5 let
6   cfg = config.services.logcheck;
8   defaultRules = pkgs.runCommand "logcheck-default-rules" { preferLocalBuild = true; } ''
9                    cp -prd ${pkgs.logcheck}/etc/logcheck $out
10                    chmod u+w $out
11                    rm -r $out/logcheck.*
12                  '';
14   rulesDir = pkgs.symlinkJoin
15     { name = "logcheck-rules-dir";
16       paths = ([ defaultRules ] ++ cfg.extraRulesDirs);
17     };
19   configFile = pkgs.writeText "logcheck.conf" cfg.config;
21   logFiles = pkgs.writeText "logcheck.logfiles" cfg.files;
23   flags = "-r ${rulesDir} -c ${configFile} -L ${logFiles} -${levelFlag} -m ${cfg.mailTo}";
25   levelFlag = getAttrFromPath [cfg.level]
26     { paranoid    = "p";
27       server      = "s";
28       workstation = "w";
29     };
31   cronJob = ''
32     @reboot   logcheck env PATH=/run/wrappers/bin:$PATH nice -n10 ${pkgs.logcheck}/sbin/logcheck -R ${flags}
33     2 ${cfg.timeOfDay} * * * logcheck env PATH=/run/wrappers/bin:$PATH nice -n10 ${pkgs.logcheck}/sbin/logcheck ${flags}
34   '';
36   writeIgnoreRule = name: {level, regex, ...}:
37     pkgs.writeTextFile
38       { inherit name;
39         destination = "/ignore.d.${level}/${name}";
40         text = ''
41           ^\w{3} [ :[:digit:]]{11} [._[:alnum:]-]+ ${regex}
42         '';
43       };
45   writeIgnoreCronRule = name: {level, user, regex, cmdline, ...}:
46     let escapeRegex = escape (stringToCharacters "\\[]{}()^$?*+|.");
47         cmdline_ = builtins.unsafeDiscardStringContext cmdline;
48         re = if regex != "" then regex else if cmdline_ == "" then ".*" else escapeRegex cmdline_;
49     in writeIgnoreRule "cron-${name}" {
50       inherit level;
51       regex = ''
52         (/usr/bin/)?cron\[[0-9]+\]: \(${user}\) CMD \(${re}\)$
53       '';
54     };
56   levelOption = mkOption {
57     default = "server";
58     type = types.enum [ "workstation" "server" "paranoid" ];
59     description = lib.mdDoc ''
60       Set the logcheck level.
61     '';
62   };
64   ignoreOptions = {
65     options = {
66       level = levelOption;
68       regex = mkOption {
69         default = "";
70         type = types.str;
71         description = lib.mdDoc ''
72           Regex specifying which log lines to ignore.
73         '';
74       };
75     };
76   };
78   ignoreCronOptions = {
79     options = {
80       user = mkOption {
81         default = "root";
82         type = types.str;
83         description = lib.mdDoc ''
84           User that runs the cronjob.
85         '';
86       };
88       cmdline = mkOption {
89         default = "";
90         type = types.str;
91         description = lib.mdDoc ''
92           Command line for the cron job. Will be turned into a regex for the logcheck ignore rule.
93         '';
94       };
96       timeArgs = mkOption {
97         default = null;
98         type = types.nullOr (types.str);
99         example = "02 06 * * *";
100         description = lib.mdDoc ''
101           "min hr dom mon dow" crontab time args, to auto-create a cronjob too.
102           Leave at null to not do this and just add a logcheck ignore rule.
103         '';
104       };
105     };
106   };
110   options = {
111     services.logcheck = {
112       enable = mkEnableOption (lib.mdDoc "logcheck cron job");
114       user = mkOption {
115         default = "logcheck";
116         type = types.str;
117         description = lib.mdDoc ''
118           Username for the logcheck user.
119         '';
120       };
122       timeOfDay = mkOption {
123         default = "*";
124         example = "6";
125         type = types.str;
126         description = lib.mdDoc ''
127           Time of day to run logcheck. A logcheck will be scheduled at xx:02 each day.
128           Leave default (*) to run every hour. Of course when nothing special was logged,
129           logcheck will be silent.
130         '';
131       };
133       mailTo = mkOption {
134         default = "root";
135         example = "you@domain.com";
136         type = types.str;
137         description = lib.mdDoc ''
138           Email address to send reports to.
139         '';
140       };
142       level = mkOption {
143         default = "server";
144         type = types.str;
145         description = lib.mdDoc ''
146           Set the logcheck level. Either "workstation", "server", or "paranoid".
147         '';
148       };
150       config = mkOption {
151         default = "FQDN=1";
152         type = types.lines;
153         description = lib.mdDoc ''
154           Config options that you would like in logcheck.conf.
155         '';
156       };
158       files = mkOption {
159         default = [ "/var/log/messages" ];
160         type = types.listOf types.path;
161         example = [ "/var/log/messages" "/var/log/mail" ];
162         description = lib.mdDoc ''
163           Which log files to check.
164         '';
165       };
167       extraRulesDirs = mkOption {
168         default = [];
169         example = [ "/etc/logcheck" ];
170         type = types.listOf types.path;
171         description = lib.mdDoc ''
172           Directories with extra rules.
173         '';
174       };
176       ignore = mkOption {
177         default = {};
178         description = lib.mdDoc ''
179           This option defines extra ignore rules.
180         '';
181         type = with types; attrsOf (submodule ignoreOptions);
182       };
184       ignoreCron = mkOption {
185         default = {};
186         description = lib.mdDoc ''
187           This option defines extra ignore rules for cronjobs.
188         '';
189         type = with types; attrsOf (submodule ignoreCronOptions);
190       };
192       extraGroups = mkOption {
193         default = [];
194         type = types.listOf types.str;
195         example = [ "postdrop" "mongodb" ];
196         description = lib.mdDoc ''
197           Extra groups for the logcheck user, for example to be able to use sendmail,
198           or to access certain log files.
199         '';
200       };
202     };
203   };
205   config = mkIf cfg.enable {
206     services.logcheck.extraRulesDirs =
207         mapAttrsToList writeIgnoreRule cfg.ignore
208         ++ mapAttrsToList writeIgnoreCronRule cfg.ignoreCron;
210     users.users = optionalAttrs (cfg.user == "logcheck") {
211       logcheck = {
212         group = "logcheck";
213         isSystemUser = true;
214         shell = "/bin/sh";
215         description = "Logcheck user account";
216         extraGroups = cfg.extraGroups;
217       };
218     };
219     users.groups = optionalAttrs (cfg.user == "logcheck") {
220       logcheck = {};
221     };
223     system.activationScripts.logcheck = ''
224       mkdir -m 700 -p /var/{lib,lock}/logcheck
225       chown ${cfg.user} /var/{lib,lock}/logcheck
226     '';
228     services.cron.systemCronJobs =
229         let withTime = name: {timeArgs, ...}: timeArgs != null;
230             mkCron = name: {user, cmdline, timeArgs, ...}: ''
231               ${timeArgs} ${user} ${cmdline}
232             '';
233         in mapAttrsToList mkCron (filterAttrs withTime cfg.ignoreCron)
234            ++ [ cronJob ];
235   };