Archive log files using logrotate preremove

Saturday, 12 March 2016

Why? Keep log files for as long as required, whilst mitigating the risk of the archive growing to fill the device holding /var/log.

How? Using the preremove directive with logrotate version 3.8.4 and higher. To Paraphrase the logrotate manpage: "The lines between preremove and endscript are executed (using /bin/sh) once just before removal of a log file. The logrotate will pass the name of the file which is soon to be removed."

A log file is removed so that no more than rotate rotated files exist and the preremove script affords the opportunity to archive a copy of the soon to be removed file.

Here's an example configuration script for /var/log/syslog:-

/var/log/syslog
{
    rotate 1
    daily
    missingok
    notifempty
    delaycompress
    compress
    dateext
    dateyesterday

    preremove
        if file --mime-type "$1" | grep -q gzip$; then \
            cp -p "$1" /path/to/archive/syslog/; \
        fi; \
    endscript

    postrotate
        reload rsyslog >/dev/null 2>&1 || true
    endscript
}

A file is also removed after its content has been compressed and output to a separate file, when the compress directive is present. The preremove script can therefore receive the path to either an uncompressed or a compressed file, when compress is present . Hence, the preremove script in this example tests the mime-type of the file being removed to ensure that only compressed files are archived.

The dateext directive is used to avoid file naming conflicts at the destination: the default dateformat format_string, -%Y%m%d, is fine for a file being rotated no more frequently than once daily.