First of all, each filter must process data from one or more "Logfile Group". *********************************************** * Logfile Groups *********************************************** Logfile groups are defined by a configuration file in /etc/log.d/conf/logfiles named .conf. It is usually easier to copy an existing logfile group configuration than it is to create a brand new one. There is only one required line in the logfile group config file. This command is called 'LogFile'. # This will be the logfile named 'messages' in the default logfile # directory (probably /var/log). LogFile = messages # You can also give this command with an absolute path, like this: LogFile = /var/log/messages You can have as many LogFile entries as you wish. All the files specified will be merged into one input stream for any filters that use this logfile group. You can also use standard wildcards when you specify the filename. Another command that is optional is called 'Archive'. You can specify a file to also include in the data stream if the '--archives' option is used. If these files do not exist it is okay. For example: # These 2 'Archive' entries will allow users of most Red Hat Linux # systems to access their archives of the 'messages' logfile: Archive = messages.? # If they configure Compression to be on in /etc/logrotate.conf: Archive = messages.?.gz # It is best just to include both of these so that the logfile group # will work for most systems. Now, the general theory is that the LogFile Group should apply the date range requested. If the logfile is in the standard syslog format, you can use the shared script 'ApplyStdDate' to filter out only the appropriate log entries. The way to call shared scripts (located in /etc/log.d/scripts/shared) is: *ApplyStdDate = Anything following the equal sign will be passed to the program as arguments (the equal sign can be eliminated if no arguments are needed). You should look at the current logfile group config files for examples. Finally, if the directory /etc/log.d/scripts/logfiles// exists, any scripts in that directory will be executed. All of these scripts take the contents of all the specified logfiles in through STDIN and output the modified logfile trought STDOUT. These scripts can be written in any language that can be executed on your system. *********************************************** * Service Filter Configuration File *********************************************** Okay, once you have defined one or more logfile groups (or decided on one or more existing logfile groups), you need to define your service filter. This file needs to be in /etc/log.d/conf/services/ and it needs to be named service.conf. You should probably copy an existing config for another service to create a new one. There is only one required line. This is the command 'LogFile'. The LogFile command allows you to specify one or more *LogFile Groups* (as described above) that this filter will process. Remember, any filter can process any number of LogFile Groups, and any LogFile Group may contain the data from any number of logfiles (and archives). For a service filter that needs messages from /var/log/messages you would add this line: LogFile = messages NOTE: This is *not* because the name of the logfile is 'messages', but it is because the name of the LogFile Group that has been defined is 'messages'. You can have commands in the form of: *SharedScriptName = Arguments that will execute a script found in the /etc/log.d/scripts/shared/ directory named 'SharedScriptName' with arguments 'Arguments'. This filter will modify the input to the service's filter. You can also have commands in the form: $EnvironmentVariable = Value This command will set the 'EnvironmentVariable' environment variable to the value 'Value'. This environment variable will be accessable by your filter program. You will also usually want to specify a title for your script (new in Logwatch 4.0). If specified, then a start and stop delimiter will be added by Logwatch for your specific service (with your script's output between those delimiters). This will *only* happen if you produce output. If you produce no output, the headers will not be created. Here is how you define your title: Title = "My Service Title" *********************************************** * Service Filter Executable *********************************************** Once everything above has been done, you are ready to actually write your filter. This can be done in any language as all it does is: 1) Read logfile entries from STDIN 2) Access some environment variables 3) Generate a report on STDOUT Before you try to write a filter, you should create the filter and make its contents the test script given below. The filter needs to be located in /etc/log.d/scripts/services/ and named service (because you named the config file service.conf). ###################### Cut Here ######################### #!/bin/bash # This is as nice script that will show you the lines you will # be processing and reporting on. It will first display the # standard environment variables and then it takes STDIN and # dump it right back out to STDOUT. # These are the standard environment variables. You can define # more in your service config file (see above). echo "Date Range: $LOGWATCH_DATE_RANGE" echo "Detail Level: $LOGWATCH_DETAIL_LEVEL" echo "Temp Dir: $LOGWATCH_TEMP_DIR" echo "Debug Level: $LOGWATCH_DEBUG" # Now take STDIN and dump it to STDOUT cat ###################### Cut Here ######################### If you temorarily replace a script such as 'pam' with the above, you will notice that much has been cut out of /var/log/messages before it gets to this filter. The value of the environment variable LOGWATCH_DETAIL_LEVEL can be any integer. In reality, it is usually 0 (for low), 5 (for medium), and 10 (for high). Your script should only produce output as appropriate. If there are no relevant log entries, no output should be produced. Likewise, if you are reporting two things, such as "Good Logins" and "Bad Logins", you should only produce even the headers when appropriate. For example: Bad Logins: amber (2 time(s)) kirk (3 time(s)) Good Logins: amber (5 time(s)) kirk (10 time(s)) But, if no failed logins occur, you should only output: Good Logins: amber (5 time(s)) kirk (10 time(s)) Note that there is no "Bad Logins:" header as there were no bad logins. You should also use the detail environment variable when deciding what to output. Bad logins might always be displayed, but good logins might only be displayed at higher detail levels. Here is a guide on how you should use the detail setting: 0 (Low): Display only errors and security-related issues 5 (Med): Display anything that a typical administator would be interested in 10 (High): Display anything that a paranoid administrator would want to see In some cases, you can use a security setting higher than 10. This would be reserved for information so trivial that it would not even interest the US Government.