Назад | Перейти на главную страницу

Как совместить logrotate с «катящимся» файловым приложением Log4j?

У нас есть Java-приложение, которое использует log4j и ежедневно меняет собственные логи:

Мы бы предпочли не менять его конфигурацию ...

Однако мы хотим:

  1. Сжать файл после переименования
  2. Сохраняйте только определенное количество из них

Хотя написать cron-задание для обоих подходов не составит труда, мы предпочли бы остаться в рамках logrotate...

Я создаю следующие /etc/logrotate.d/foo:

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

но ничего не делает:

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

Как заставить его сжать файлы и удалить самые старые, когда их общее количество превышает 2?

Мне нужно было добиться этого, потому что команды разработчиков приложений хотели сохранить контроль над журналом и форматом имени файла, а также графиком ротации с помощью log4j. Если вы читаете man logrotate вы заметите, что все сценарии pre / post / lastaction выполняются только тогда, когда был повернут хотя бы один журнал. Таким образом, установив что-то недоступное, например size 999G не работает.

Вместо этого я установил copy и extension варианты так, чтобы:

  1. Исходный файл журнала не был изменен (им управляет log4j)
  2. Журналы, повернутые с помощью logrotate, имеют другое расширение, которое я могу фильтровать.
/var/log/<service>/<service>.log {
    copy  # don't touch the orig. log file, it's managed by log4j
    extension .log  # End rotated files in ".log" so we can find and delete them
    rotate 1
    hourly
    missingok

    prerotate
        find /var/log/<service>/ -iname "*service.log.*" ! -iname "*.gz" -exec gzip {} \; && \
        aws s3 sync /var/log/<service>/ s3://<bucket>/<environment>/<ec2_id>/<service>/ --exclude "*" --include "*<service>*.gz" && \
        find /var/log/<service>/ -iname "*<service>.log.*" -mtime +7 -delete
    endscript

    lastaction
        find /var/log/<service>/ -iname "*<service>.*.log" -delete
    endscript
}

Да, я мог бы просто сделать работу cron. Мои доводы в пользу использования logrotate заключается в том, что я сохраняю все управление конфигурацией ротации журналов в одной роли Ansible, и в будущем я буду настаивать на отключении log4j вращение и использование logrotate вместо этого будет простое изменение.

Я действительно не думаю, что ты сможешь делать то, что хочешь, с logrotate без каких-либо внешних команд. Также узор /var/log/foo/foo.log.* будет рассматривать каждый отдельный файл как отдельный журнал, подлежащий ротации, а не как набор повернутых файлов.

man logrotate

Пожалуйста, используйте подстановочные знаки с осторожностью. Если вы укажете *, logrotate повернет все файлы, включая ранее повернутые.

В любом случае, может быть что-то в этом роде? Просто установите условие поворота, которое никогда не будет достигнуто, поскольку log4j уже частично обрабатывает поворот. Затем положите остальное в prerotate сценарий?

/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
}

Приложения для динамического файла Log4j и logrotate несовместимы. Вращение log4j будет мешать logrotate.

Сначала вам нужно найти файл конфигурации log4j для приложения и заменить Rolling File Appenders простыми File Appenders. Это остановит log4j от вращения файлов. Затем вы можете использовать logrotate для вращения файлов журнала по своему усмотрению.

Если вы не можете изменить конфигурацию log4j приложения, вы можете создать свою собственную и указать ее в пути к классам при запуске приложения.

-Dlog4j.configurationFile=path/to/log4j2.xml

Ссылка: https://logging.apache.org/log4j/2.0/faq.html#config_location