Please see Learning Rsyslog for the introduction and index to this series of blog posts about Rsyslog.
Let's start with the result of a basic logger command:
$ logger "GO log test 43"
As root (/var/log/messages isn't usually visible to regular users) we look at the output in the log:
Oct 24 18:17:33 sli7-f giles: GO log test 43
Notice that it's tagged with the date and time, the hostname ("sli7-f"), the user who sent the message ("giles"), and the process ID in square brackets. This is from Fedora; on Debian, it's essentially the same minus the PID. Let's start trying to control the "facility," "priority," and "tagging:"
$ logger -p local0.notice -t MYTAG "GO logging test 6"
The resulting output looks like this:
Oct 23 17:26:56 toshi7fed MYTAG: GO logging test 6
Notice the facility and priority don't get recorded here - and that "tagging" defaults to the user name but can be over-ridden by providing a word as a tag.
Before we start making changes to /etc/rsyslog.conf, it might be a good time to install etckeeper - which is available as a package on both Debian and Fedora. Read the docs enough to get it running! It's a great service to have on any machine that's not living under Infrastructure-as-Code control.
Now let's modify the /etc/rsyslog.conf file to handle the filtering of logging we're sending:
# order matters: this goes before the /var/log/messages line: local0.* /var/log/local0.log *.info;mail.none;authpriv.none;cron.none;local0.none /var/log/messages
You'll need to restart the Rsyslog service to re-read the configuration. I've done it so often - and so often wrong - that I've taken to using
systemctl restart rsyslog ; systemctl status rsyslog | cat - this allows you to immediately see if the service is unhappy with your changes.
The above configuration tells it that anything that's marked as facility "local0" goes into the /var/log/local0.log file - and I've added ;local0.none on the line feeding /var/log/messages so that my local0 mesages appear only in the log file I've chosen. There are (inevitably!) other ways of doing this, but we're now in a position to declare that facility "local0" is associated with whatever logging project we're working on, and we've arranged that its output will all land in one specific file.
This is a possible solution and not too bad, but it seems to me it would be better to filter on tagging. So let's try something else.
# added to /etc/rsyslog.conf - before lines dealing with /var/log/messages # Look for "Filter Conditions" in the rsyslog documentation :syslogtag, startswith, "MEMORY" /var/log/memfree.log :syslogtag, startswith, "MEMORY" stop
Restart the service. This says "if you find a 'syslogtag'" (the tagging that can be added with the
logger -t ...) "then send it to /var/log/memfree.log." Remembering that messages continue to propagate (any "MEMORY" tagged message will also end up in /var/log/messages), I added another line with the "stop" command - it amounts to "don't send this message anywhere else."
[CAVEATS: "MEMORY" has to be in quotes, it's otherwise a keyword and does weird things. And I called the log file "memfree" because on Fedora there's already a /var/log/memory.log file.]
To test, we run a script like this:
tmpfile=$(mktemp /tmp/memXXXXXX) free > $tmpfile logger -t MEMORY -f $tmpfile rm $tmpfile
This is a good approximation of the script I would use on a cron job to write memory information. I've thrown in one new
logger trick, which is the use of the
-f switch that reads in a file as the log message. And with the above set-up, the output lands in /var/log/memfree.log.