Setting up logwatch
One of the parts of managing linux instances is understanding the state of the machine so it can be troubleshooted. I really needed to output logs from my machine, so I set out to learn a very well known tool for log summarization called logwatch.
There are three parts to any logwatch ‘service’. I use this term in quotes because I haven’t defined it yet, but also because it is different than the unix concept of a service. Generally it encompasses the type of logs you wish to summarize.
- A logfile configuration(located in
<logwatch_root_dir>/logfiles/mylog.conf
) - A service configuration(located in
<logwatch_root_dir>/services/mylog.conf
) - A filter script(located in
<logwatch_root_dir>/scripts/services/mylog
)
This three pieces together are what forms a service. What really helped me understand was to go through an example of one of these logs. Let’s take for example, the http-error service.
Before we continue, a note about <logwatch_root_dir>
. Logwatch internally
looks for these configuration files based on several dirs. For Ubuntu, the
lookup is /usr/share/logwatch/default.conf
> /usr/share/logwatch/dist.conf
>
/etc/logwatch/
. The idea being that each successive directory overrides
parameters from the previous location. This is covered really well here.
Logfile Configuration
|
|
Line 7-8 are basically file filters on which files from the log root will
logwatch feed into your service. This is a pretty great idea, because you could
potentially generate a custom log based on many different kinds of logs. For
example, your custom log can incorporate the number of http access errors that
were encountered by your server in a given time period. If absolute paths are
not given, paths are relative to the default log root, /var/log/
Lines 14-15 show that you can also search archive files for the same log information.
Line 21 seems to be some left over unused code, but was meant to expand the logs when standard syslog files have the message “Last Message Repeated n Times”. As the comment indicates, it just removes repeats.
Line 24 is interesting. The * indicates to the logwatch perl script to apply a
filter function to all lines of this file. At
<logwatch_root_dir>/scripts/shared/applyhttpdate
, we can see that this filters
the dates in the logs, assuming a certain header format for the lines in the
file. Logwatch provides a couple of standard filters with intuitive names like
onlycontains, remove, etc.
Service Configuration
So now we know how logwatch finds the logs that might be of interest to us. What does it do with these files? For that, we have to look at the service configuration file:
|
|
The directive on Line 2 is straightforward - what should this log be named? When the log output is generated, this is what goes in the headers.
Line 5, confusingly, tells logwatch which logfile “group” it’s interested in. This is simply the logfile configuration we looked at earlier, minus the .conf extension. However, just as the logfile configuration can filter logs with different extensions and names, the service configuration can incorporate multiple logfile groups.
Service Configuration
Finally, logwatch runs the output of all of the logs gathered by the
configurations through a script with the same name as the service configuration,
but in <logwatch_root_dir>/scripts/services/<servicename>
. Most bundled
scripts are perl scripts, but the great thing is that you can pretty much use
any scripting language.
I won’t actually go through /usr/share/logwatch/scripts/services/http-error
here, one because it’s pretty long, and two, I don’t understand perl and can’t
explain it very well : ) However, the gist of it is that it takes all the output
of all the logs and summarizes them, outputting the result in stdout.
My custom log watch doesn’t actually watch any logs, but I still need to write these three files. This was my final setup.
Logfile conf
|
|
Service conf
|
|
Script
|
|
To test, I just ran:
$ logwatch --service customlogger
--------------------- customlogger Begin ------------------------
top - 21:36:06 up 4:16, 1 user, load average: 0.12, 0.05, 0.01
Tasks: 144 total, 1 running, 143 sleeping, 0 stopped, 0 zombie
%Cpu(s): 2.4 us, 0.6 sy, 0.0 ni, 96.8 id, 0.2 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 497664 total, 43716 free, 194456 used, 259492 buff/cache
KiB Swap: 0 total, 0 free, 0 used. 280112 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
13373 root 20 0 202988 44448 12796 S 0.0 8.9 0:00.76 uwsgi
11868 root 20 0 762376 41940 8192 S 0.0 8.4 1:04.90 dockerd
13389 root 20 0 202988 35224 3568 S 0.0 7.1 0:00.00 uwsgi
13390 root 20 0 202988 35220 3564 S 0.0 7.1 0:00.00 uwsgi
13305 root 20 0 47780 15720 6432 S 0.0 3.2 0:02.16 supervisord
9024 root 20 0 290696 13876 3268 S 0.0 2.8 0:02.55 fail2ban-se+
31127 ubuntu 20 0 36412 11060 4316 S 0.0 2.2 0:00.07 logwatch
11872 root 20 0 229844 9460 2536 S 0.0 1.9 0:00.28 containerd
1162 root 20 0 266524 7372 488 S 0.0 1.5 0:00.02 snapd
27837 root 20 0 101808 6844 5868 S 0.0 1.4 0:00.00 sshd
417 root 20 0 62048 6356 3732 S 0.0 1.3 0:01.52 systemd-jou+
1 root 20 0 55208 5796 3936 S 0.0 1.2 0:04.99 systemd
13430 root 20 0 67824 5636 4896 S 0.0 1.1 0:00.02 sshd
total used free shared buff/cache available
Mem: 486 190 42 7 253 273
Swap: 0 0 0
---------------------- customlogger End -------------------------
###################### Logwatch End #########################
So if you need this to run every other hour, the last thing to do is to set up a cron job to do it. Pretty nifty, I think.
0 */2 * * * /usr/sbin/logwatch --service customlogger --output mail --mailto <your-email>