Logging CRON messages to a different file

Noticed that a lot of the messages in /var/log/syslog are from CRON and anacron?  Would you prefer that they be directed to a different file?  Easy Peasy.

I use cron to schedule the execution of a number of programs that perform a variety of tasks (e.g. backups).  By default, Ubuntu 18.04 is configured to log everything that cron does to /var/log/syslog.  I previously explained how to suppress messages from certain programs, but in this case what I just want to do is have the messages logged to a different file.

To accomplish that, you’ll need to edit rsyslog’s configuration file:

$ sudo nano /etc/rsyslog.d/50-default.conf

and edit the two lines that look like this:

*.*;auth,authpriv.none   -/var/log/syslog
#cron.*                  /var/log/cron.log

so they look like this:

*.*;auth,authpriv,cron.none  /var/log/syslog
cron.*                       /var/log/cron

Basically, you want to accomplish two things:

  1. You want to stop logging cron messages to /var/log/syslog
  2. You want to start logging cron messages to /var/log/cron (or some other file)

Adding ‘,cron’ to the first line accomplishes 1.  Removing the ‘#’ from the second line accomplishes 2.

For the changes to take effect, just restart the rsyslog daemon:

$ sudo service rsyslog restart

The next time a cron job runs /var/log/cron will be created and that’s where cron will log all of its messages from that point on.  Ditto for anacron.

That’s it.  You’re done.  Enjoy!

But wait…

Q:  Can you explain how *.*;auth,authpriv,cron.none /var/log/syslog works?

Sure.  Each message has a facility and a severity.

The facility indicates the type of service that the program is providing (e.g. kernel, mail, cron, authentication).  You can find a full list here.  Multiple programs that perform similar or related functions can use the same facility when logging messages.  In this case the programs ‘cron’ and ‘anacron’ both specify ‘cron’ as the facility.  Facility names were developed a long time ago — often in a context where only one program existed that provided a particular service — so many times the name of the facility is the same as the name of a program.

The severity was explained in the last blog post on this topic.

You can mix and match facilities and severities using the . (dot) notation where the facility is specified before the dot and severity is specified after the dot.  A * (asterisk) is a wildcard that matches all facilities and severities — depending on what side of the dot it appears.

Examples:

  • cron.err will only match cron messages issued with a severity level of ‘error’
  • cron.warning will match all cron warnings
  • cron.* will match all cron messages, regardless of severity
  • *.err will match all error messages, regardless of what facility they were logged under
  • *.* matches all messages from all facilities regardless of severity

Thus something like *.*  /var/log/syslog is all you need to log all messages to syslog.  It’s like a ‘catch all’.

Now, if you want to specify multiple things to be logged to the same file, you can use a semi-colon like this:  auth.alert;cron:err  /var/log/myCustomLog

If you want to treat groups of messages of a given severity level the same way (e.g. mail.err;cron.err) you can chain together the different facilities using commas like this:  mail,cron.err  /var/log/myCustomLog

Finally, there is a special type of ‘severity’ that only works inside rsyslog, and that’s ‘none’.  The ‘none’ severity simply means “don’t log it” or, perhaps more subtly, “none of these message should be included in this log”.  Thus cron.none /var/log/syslog makes sure that no cron messages will be logged in syslog.

You can combine * ; , and none all on the same line, so what *.*;auth,authpriv,cron.none /var/log/syslog actually means is:

  • log all facilities and severities
  • but log none of the messages from auth,authpriv,cron
  • to the file /var/log/syslog

Once you break it down it’s not too tricky.

Q: What does the hypen in front of the filename mean?

Astute readers probably noticed a hyphen in front of some of the filenames in /etc/rsyslog.d/50-default.conf (e.g. -/var/log/syslog).  And yes, they are hyphens, not tildes.

In the old days — when drives and systems were really slow and unreliable — it was risky to hold back (buffer) log entries in memory and then ‘sync’ them to disk all in one hit.  Sure, it improved performance, but you could lose (sometimes important) log entries if the system went down.  Thus rsyslog defaulted to immediately syncing/flushing out writes.  A user that wanted to ‘switch off’ the syncing, and buffer writes for improved performance, could prepend a log file name with a hyphen.  Thus -/var/log/syslog once meant “don’t sync writes to syslog”.  The hyphen was a ‘sync switch’.

Times changed, system reliability improved, and at some point the folks who develop rsyslog decided that the default behaviour should be changed.  Now writes are not synced by default — they are buffered.  The hyphen doesn’t actually do anything anymore — unless you add an $ActionFileEnableSync on entry to /etc/rsyslog.conf.

You can happily ignore the hyphens on any modern system.  Strip them out if you like (as I did above)  — it makes no difference because they are ignored anyway.  They are just artefacts from the past.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s