logrotate: автоматическая ротация и архивация логов
Логи приложений забивают диск за неделю, а rm *.log вручную — путь к проблемам. logrotate решает это сам: ротирует, сжимает и удаляет старые файлы по расписанию. Разберёмся, как это работает и как настроить за пять минут.
Как это устроено
logrotate вызывается через cron ежедневно. Конфиг по умолчанию живёт в /etc/logrotate.conf, а дополнительные конфиги подключаются из /etc/logrotate.d/. При ротации текущий файл переименовывается, создаётся новый пустой, старые копии сжимаются и нумеруются.
Цикл простой:
Механизм работает через rename или mv, поэтому процесс должен держать дескриптор открытым. Если ротация не подхватывается приложением — получаете дублирование или пустой лог.
Структура конфигурации
Файлы из /etc/logrotate.d/ перекрывают глобальные значения для конкретных логов. Формат простой:
Директивы наследуются от глобального конфига, если не переопределены. Можно указать несколько путей через пробел или шаблон — это удобно для ротации всех логов приложения одним блоком.
Ключевые директивы
Базовые параметры, которые закрывают 90% задач:
| Директива | Назначение | Пример |
|---|---|---|
rotate N | сколько копий хранить | rotate 7 |
size N | размер для триггера ротации | size 100M |
missingok | не ошибка, если файла нет | — |
notifempty | пропустить пустой лог | — |
compress | сжимать старые (по умолчанию gzip) | — |
dateext | дата вместо номера в имени | — |
dateformat | формат даты | dateformat -%Y%m%d |
postrotate ... endscript | команды после ротации | reload сервиса |
prerotate ... endscript | команды до ротации | prepare директории |
size отменяет weekly/monthly/daily, если задан. Ротация происходит когда файл достигает указанного размера И прошёл интервал. То есть size 100M при weekly — ротация не раньше недели и если файл больше 100М.
dateext несовместим с длинными именами файлов на некоторых файловых системах. Если имя лога + суффикс даты выходит за 255 байт — logrotate упадёт.
Пример конфига для приложения
Допустим, у нас сервис myapp пишет в /var/log/myapp/. Конфиг:
sharedscripts гарантирует один вызов postrotate для всех ротируемых файлов, а не для каждого. Без него скрипт выполняется столько раз, сколько файлов подпало под ротацию.
Для Python-приложений с ротацией через стандартный library:
su меняет владельца процесса ротации — полезно, если приложение запущено под отдельным пользователем и права на логи ограничены.
Отладка и принудительный запуск
dry-run режим показывает что будет сделано без реальных действий:
Вывод содержит каждое решение: какой файл переименовывается, какой сжимается, какие команды выполняются. Смотрите на строки renaming и running postrotate script.
Принудительная ротация минуя расписание:
-f игнорирует время последней ротации и размеровые условия. Комбинация с -d — безопасный способ проверить перед продакшеном:
Если нужно ротировать конкретный лог вне расписания, но с учётом условий — используйте state-файл:
Проверка синтаксиса без выполнения:
Если ошибок нет — вывод пустой (без -d) или показывает план действий (с -d).
Не редактируйте /var/lib/logrotate/status вручную в продакшене без понимания формата. Одна ошибка — и logrotate решит что ротация уже прошла, пропустит все файлы до следующего запуска cron.
Настройка cron по умолчанию:
В большинстве дистрибутивов трогать этот файл не нужно. Если нужен запуск чаще раза в сутки — добавляйте в /etc/cron.hourly/ или пишите отдельный cron job.