How to combine logrotate with Log4j “rolling” file-appender

log4jlogrotate

We have a Java-application, that uses log4j and rotates its own logs daily:

  • The currently-used log-file is /var/log/foo/foo.log
  • It is moved into /var/log/foo/foo.log.YYYY-MM-dd when the day changes

We'd rather not change its configuration…

However, we do want to:

  1. Compress the file once it has been renamed
  2. Only retain a certain number of them

Though it wouldn't be difficult to write a cron-job to do both, we'd rather stay in the framework of logrotate

I create the following /etc/logrotate.d/foo:

/var/log/foo/foo.log.* {
        daily
        rotate 2
        compress
        delaycompress
        missingok
        notifempty
}

but it does not do anything:

reading config file /etc/logrotate.d/foo

Handling 1 logs

rotating pattern: /var/log/foo/foo.log.*  after 1 days (2 rotations)
empty log files are not rotated, old logs are removed
considering log /var/log/foo/foo.log.2017-06-28
  log does not need rotating
considering log /var/log/foo/foo.log.2017-06-29
  log does not need rotating
considering log /var/log/foo/foo.log.2017-06-30
  log does not need rotating
considering log /var/log/foo/foo.log.2017-07-01
  log does not need rotating
considering log /var/log/foo/foo.log.2017-07-02
  log does not need rotating
considering log /var/log/foo/foo.log.2017-07-03
  log does not need rotating
considering log /var/log/foo/foo.log.2017-07-04
  log does not need rotating

How do I make it compress the files and delete the oldest ones, when their total number exceeds 2?

Best Answer

I really don't think you are going be able to do what you want with logrotate without some external commands. Also, the pattern /var/log/foo/foo.log.* would treat each individual file as if it was a separate log to be rotated, not as a set of rotated files.

man logrotate

Please use wildcards with caution. If you specify *, logrotate will rotate all files, including previously rotated ones.

Anyway, maybe something like this? Just set your rotate condition that will never be reached since log4j is already handling the rotation partly. Then put the rest in a prerotate script?

/var/log/foo/foo.log {
    size 100G # something big that will never be reached/rotated since log4j does this.
    missingok
    notifempty
    # delete the other logs over 7 days old
    prerotate
        find /var/log/foo/ -name 'foo.log.*' -mtime +7 -delete
        nice gzip /var/log/foo/foo.log.*
    endscript
}