8

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?

Stefan Lasiewski
  • 23,667
  • 41
  • 132
  • 186
Ether
  • 322
  • 3
  • 12

3 Answers3

2

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.

Old Pro
  • 1,425
  • 12
  • 21
  • 3
    The problem is the same as if I had the override in a single file (which is legal): if I have an override, I can't then use a wildcard for the rest of the files in that directory, without the error that I quoted in the question. If I am wrong, please provide a working example? – Ether May 12 '12 at 00:54
  • 1
    @Ether, I'm still looking into it, but 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. For now, use a wild card that excludes the files you want to set with different options. – Old Pro May 12 '12 at 15:48
  • 2
    wildcards can't do exclusions - there is no way to say "everything but this one file". – Ether May 14 '12 at 16:31
  • 2
    @Ether, true, you cannot specify "everything but this one file" in a wild card, but you could do something like `[a-hj-z]*` to select all files that begin with a lower case letter other than `i`. If your special file is the only one whose name begins with `i` then that would be "a wild card that excludes the files you want to set with different options". – Old Pro May 14 '12 at 23:14
  • 4
    You could also change the application configuration to log the files you want to treat special into a different directory... I don't think logrotate is nearly sophisticated enough to do what you want or, in fact, should be. If the app is making arbitrarily named logs maybe you could put THOSE someplace different and then spec every log in this directory in two or three lists. – Mark May 15 '12 at 15:11
  • Separate files or order in files doesn't work, overlapping paths, such as those that might result from specific paths and wildcard paths, are not permitted. Or please update with a working example. – javabrett May 16 '15 at 02:01
2

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.

javabrett
  • 153
  • 8
  • @HasK - thanks for your pending edit - can you mention the distro, version, user, shell and other details the test failed with? Note that the above are not recommended workarounds and are bound to be fragile. – javabrett Dec 25 '19 at 22:23
1

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.

HasK
  • 11
  • 1