Ротация логов Nginx и Apache через logrotate без простоя (Zero-Downtime)
- Файлы
access.logразрастаются до сотен гигабайт и переполняют корневой диск сервера. - После ротации веб-сервер перестает записывать логи в новый файл, удерживая удаленный дескриптор.
- Кратковременный сбой обслуживания клиентов (Downtime) при некорректном перезапуске сервиса через
systemctl restart.
1. Настройка ротации Nginx без разрыва соединений
Отредактируйте файл /etc/logrotate.d/nginx:
/var/log/nginx/*.log {
daily
missingok
rotate 14
compress
delaycompress
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
# Отправка сигнала USR1 ядру Nginx для переоткрытия дескрипторов на лету
[ -f /run/nginx.pid ] && kill -USR1 $(cat /run/nginx.pid)
endscript
}2. Настройка ротации Apache без простоя
Отредактируйте файл /etc/logrotate.d/apache2 (или httpd):
/var/log/apache2/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 640 root adm
sharedscripts
postrotate
# Мягкая перезагрузка apache без разрыва активных соединений
/usr/sbin/apachectl graceful > /dev/null 2>&1 || true
endscript
}3. Ручной тестовый прогон утилиты logrotate
# Запуск принудительной ротации в режиме отладки (debug)
logrotate -d /etc/logrotate.d/nginx
# Принудительное выполнение боевой ротации
logrotate -f /etc/logrotate.d/nginx Частые вопросы (FAQ)
Почему Nginx требует отправки сигнала USR1?
После того как logrotate переименовывает access.log в access.log.1, воркеры Nginx продолжают писать в старый inode. Сигнал kill -USR1 заставляет Nginx переоткрыть файл по оригинальному имени без рестарта.
Зачем нужна директива delaycompress?
Она откладывает сжатие только что ротированного файла (.1) до следующего цикла. Это гарантирует, что процессы, которые еще не успели переключить дескриптор, не запишут данные в сжимаемый архив.