How can I specify multiple rules for a particular log file(s) with logrotate?

I have a logrotate.d config file that looks something like this:

/home/myapp/log/* {
    daily
    compress
    dateext
    ifempty
    delaycompress
    olddir /home/myapp/baklog
}

There are a few particular log files where I want to apply additional rules, such as "mail". How can I apply additional rules to just some files?

If I add another rule above that matches the additional files (e.g. /home/myapp/log/warning.log { ... }, I get an error like error: /etc/logrotate.d/myapp:3 duplicate log entry for /home/myapp/log/warning.log.

How can I specify multiple rules that match particular files in an overlapping kind of way?


As Ether observes, overlapping paths are intentionally forbidden.

If you are willing and able to run logrotate with shell option extglob enabled (shopt -s extglob in the root environment running crontab logrotate), or it is already set (check with shopt extglob in the same environment), then you can create explicit path exclusions, which logrotate.conf doesn't otherwise provide for. You would need to declare each such exclusion. Of course a better solution is to reconfigure the logging system to use separate directories for the files requiring special-handling, if that is an option.

With extglob you can declare the following:

/home/myapp/log/!(warning.log) {
    daily
    compress
    dateext
    ifempty
    delaycompress
    olddir /home/myapp/baklog
}

... and the !(warning.log) will match all files except that one, allowing you to write specific rules for it. This is messy and introduces some maintenance, so again it is far better if you can configure your application's logging system to log high-priority or other special log files to a separate directory.


In most distros, you can't do that.

It looks like there was a decision made in Debian that allowing overrides of a rule for a specific file was bad because it became common for package installs to erroneously install duplicate rules and the logrotate maintainers wanted to flag that as an error.

So one way or another, whether it is by using more specific wild cards (log/[a-hj-z]* instead of log/*) so the general rule does not get applied to the exceptional log files or by changing your app config to put the exceptional log files in a different directory, you have to work it out so there are not multiple rules targeting the same log file.


You cannot.

The mentioned shopt -s extglob option is not working now. I spent several hours trying to use it without any success.

Tested on the Debian 10 (buster, bash version 5.0-4, logrotate version 3.14.0-4) and Manjaro (Arch-based).

There is an issue on the logrotate GitHub to enable such extglob support but no good news for now.