Разделение логов по часу с помощью logrotate и сжатие с использованием zstd
Сервер
Lastmod: 2023-11-30
Published: 2021-03-29

Записываю заметки о том, как разделить логи nginx по часу с помощью logrotate и сжать их с помощью zstd.

Обзор

Если просто добавить настройки в /etc/logrotate.conf или /etc/logrotate.d/, то по умолчанию
они будут выполняться через ежедневный CRON в /etc/cron.daily/logrotate.

Поскольку нам нужно выполнять ротацию логов каждый час, мы создадим отдельные настройки logrotate
и будем использовать функцию таймера systemd для их выполнения.

Установка zstd

# apt install zstd

logrotate

Создадим файл /etc/logrotate-nginx.conf.
Хотя мы используем zstd, при желании его можно заменить на bzip2, изменив настройки аналогичным образом.

# cat << _EOF_ > /etc/logrotate-nginx.conf
compresscmd /usr/bin/zstd # путь к zstd
compressoptions -12       # параметры для zstd. Лично мне понравился -12
compressext .zst          # добавляемое расширение

/var/log/nginx/*.log {
        missingok
        rotate 720 # 24 часа * 30 дней 
        dateext
        dateformat -%Y%m%d%H
        compress
        notifempty
        create 0640 www-data adm
        sharedscripts
        prerotate
                if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
                        run-parts /etc/logrotate.d/httpd-prerotate; \
                fi \
        endscript
        postrotate
                invoke-rc.d nginx rotate >/dev/null 2>&1
        endscript
}
_EOF_

systemd

  • Определение сервиса
# cat << _EOF_ > /etc/systemd/system/logrotate-nginx.service
[Unit]
Description=logrotate-nginx
After=network.target
[Service]
Type=simple
ExecStart=/usr/sbin/logrotate -f /etc/logrotate-nginx.conf
PrivateTmp=true
[Install]
WantedBy=multi-user.target
_EOF_
  • Определение таймера
# cat << _EOF_ > /etc/systemd/system/logrotate-nginx.timer
[Unit]
Description=logrotate-nginx
[Timer]
OnCalendar=*:00:00
[Install]
WantedBy=timers.target
_EOF_
  • Загрузка конфигурации systemd
# systemctl daemon-reload
  • Включение таймера
# systemctl enable logrotate-nginx.timer
  • Запуск таймера
# systemctl start logrotate-nginx.timer
  • Проверка статуса таймера
# systemctl status logrotate-nginx.timer
● logrotate-nginx.timer - logrotate-nginx
     Loaded: loaded (/etc/systemd/system/logrotate-nginx.timer; enabled; vendor preset: enabled)
     Active: active (running) since Mon 2021-03-29 20:00:00 JST; 5h 58min ago
    Trigger: n/a
   Triggers: ● logrotate-nginx.service

Mar 29 19:00:00 log systemd[1]: Started logrotate-nginx.

По статусу “Active” можно узнать время следующего запуска, а также время прошлых запусков 🎉

Добавление в ноябре 2023 года

Если вам нужно делить логи с интервалом в 1 минуту, могут возникнуть несоответствия из-за точности таймера,
в результате чего в логи будут попадать неожиданные временные метки.

Чтобы гарантированно запускать каждый раз ровно в 0 секунд, выполните настройки, аналогичные следующим:

[Unit]
Description=logrotate-nginx
[Timer]
OnCalendar=*:*:00
AccuracySec=1s
[Install]
WantedBy=timers.target

Указав AccuracySec, можно добиться выполнения с точностью до 1 секунды.