#34 Add support for systemd's journal

Unstable (example)
Mark Grimes

The attached patch will allow logwatch to parse systemd journal entries. It checks the logfile config for a "Journal" entry and uses that as a filter to journalctl. As an example, a user can switch the postfix service from using /var/log/maillog to the journal by creating a /etc/logwatch/conf/logfiles/maillog.conf with the following:

Journal = "_SYSTEMD_UNIT=postfix.service"

I've tried to keep the changes to a minimum, but I've also included a separate patch that makes testing a bit easier. It looks for the LOGWATCH_TEST env variable. If it exists, it expects to find all the config/etc files under that directory. Of course, the journal patch doesn't depend on the testing patch.

I'm happy to do additional work on this if it is well received. It could certainly be more efficient, and it needs to be documented.


2 Attachments


  • From a quick view, it seems that you run journalctl without any time limits... It would be much better to include a --since= setting, because otherwise the output will probably included a lot of old entries. It would be even better to use --show-cursor / --after-cursor, but this would require storing the cursor somewhere.

  • Mark Grimes
    Mark Grimes

    I've updated the patches to include the --since argument to journalctl based on the requested range. This will be much more efficient for the typical "yesterday" range.

  • Bjorn

    I'm not familiar with journalctl, but...

    I wonder if the journalctl processing can be done with existing facilities. In the configuration files (logfiles and services), if the first character is an asterisk '*', the key following it denotes an executable. Its parameters follow as the value, after the equals '=' sign, if any.

    So the executable is placed in the scripts/shared directory. Even though it is called as a perl script, I think it would also work if it is a Bourne-like shell (sh, bash, dash, etc.). From this executable you can call journalctl. I also think those scripts have access to the $ENV{'LOGWATCH_DATE_RANGE'}, so you could pass proper parameters to the journalctl --since and --until options.

    Now, I believe that journalctl does not take a file as an input (stdin). And yet, it appears that logwatch wants to 'cat' a log file to the declared executable. A hack would be for the executable to just ignore the input of an existing log file. (Actually, if you use the log file that journalctl uses as an input, then logwatch will check for its existence. The 'cat' is a wasted resource, however, as it appears that journalctl wants to open the file on its own.)

    An improvement would be to change logwatch.pl to allow for a declaration that indicates the executables should be run even if no logfiles/archives are declared. Or allow a declaration like LogFile=/dev/null to mean what it intuitively does: there is no logfile, but we want the declared executables to run anyway.

  • Mark Grimes
    Mark Grimes

    That is interesting. It feels a bit more like a hack, but it seems to work.

    I created an /etc/logwatch/conf/logfiles/maillog.conf file containing:

    # Clear out LogFile and give a dummy file
    LogFile =
    LogFile = "/usr/share/logwatch/README"
    # Clear out archive
    Archive =
    # Keep only the lines in the proper date range...
    # journalctl gives dates liken Mar 21 03:56:14
    *ApplyStdDate = "%b %d %H:%M:%S"
    # Provide the filter for journalctl
    *JournalCtl = "_SYSTEMD_UNIT=postfix.service"

    And put the attached in /etc/logwatch/scripts/shared. I haven't tested the date ranges all that much, but it seems to be working.