Logrotate крутит, сжимает и удаляет старые логи, чтобы /var/log не съел диск. На большинстве дистрибутивов он уже стоит и ходит по cron/systemd-timer. Ниже структура конфигов, базовые директивы и рабочие примеры для NGINX, Netdata и MariaDB, плюс dry-run для отладки.
Зачем нужен logrotate
Сервис без ротации пишет в один файл месяцами: access.log на десятки гигабайт, медленный grep, риск заполнить root. Logrotate по расписанию (или по размеру) переименовывает текущий лог, создаёт новый, при необходимости шлёт процессу сигнал reopen и сжимает архивы.
Установка и проверка
logrotate --version
Если пакета нет:
# Ubuntu/Debian sudo apt update && sudo apt install logrotate # CentOS/RHEL sudo yum install logrotate # Fedora sudo dnf install logrotate # Arch sudo pacman -S logrotate
Где живут настройки
/etc/logrotate.conf: глобальные правила по умолчанию иincludeкаталога./etc/logrotate.d/: отдельные файлы под приложения (nginx, mysql, rsyslog и т.д.).
Состояние «когда крутили последний раз» обычно в /var/lib/logrotate/status (путь может отличаться). Без state logrotate не поймёт, что daily уже отрабатывал сегодня.
Базовый /etc/logrotate.conf
weekly rotate 4 create compress include /etc/logrotate.d
weekly: ротация раз в неделю (есть ещё daily, monthly, yearly, size).rotate 4: хранить 4 поколения, старшие удалять.create: после ротации создать новый пустой лог с нужными правами.compress: gzip (или другой compressor) для архивов.include /etc/logrotate.d: подтянуть snippety сервисов.
Частые директивы в snippet-ах:
missingok: не падать, если файла нет.notifempty: не крутить пустой файл.delaycompress: сжимать не свежий архив, а предыдущий (удобно, если процесс ещё пишет в .1).sharedscripts:postrotateодин раз на весь блок, а не на каждый файл.postrotate/endscript: команды после ротации (reopen логов).
Примеры для сервисов
NGINX
Файл /etc/logrotate.d/nginx:
/var/log/nginx/*.log {
daily
missingok
rotate 7
compress
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
postrotate
[ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
endscript
}
- Ежедневно, 7 архивов.
USR1говорит nginx переоткрыть логи без полного restart (пути к pid на части систем:/run/nginx.pid).- Права
www-data:admтипичны для Debian/Ubuntu; на RHEL частоnginx:nginx.
Netdata
Файл /etc/logrotate.d/netdata:
/var/log/netdata/*.log {
weekly
missingok
rotate 4
compress
delaycompress
notifempty
create 0640 netdata netdata
sharedscripts
postrotate
systemctl restart netdata > /dev/null 2>&1 || true
endscript
}
Здесь postrotate жёстче: restart unit. Если у вашей сборки netdata умеет reopen без restart, лучше заменить на соответствующий сигнал или systemctl reload, чтобы не рвать метрики.
MariaDB / MySQL
Файл /etc/logrotate.d/mysql (имена логов сверьте с my.cnf):
/var/log/mysql/*.log /var/log/mysql/*.err {
daily
missingok
rotate 5
compress
delaycompress
notifempty
create 640 mysql adm
sharedscripts
postrotate
test -x /usr/bin/mysqladmin && /usr/bin/mysqladmin flush-logs > /dev/null 2>&1 || true
endscript
}
flush-logsзакрывает текущие файлы и открывает новые на стороне сервера.- Для binary log политика ротации часто отдельная (expire_logs_days / binlog_expire_logs_seconds), не путайте error/slow log с binlog.
Отладка
Dry-run без изменений (показывает, что сделал бы logrotate):
sudo logrotate -d /etc/logrotate.conf
Принудительный прогон с подробным логом (реально крутит, если условия выполнены):
sudo logrotate -v /etc/logrotate.conf
Прогнать один snippet «как будто пора», игнорируя state:
sudo logrotate -f -v /etc/logrotate.d/nginx
Если postrotate молчит, а процесс всё ещё пишет в access.log.1, проблема почти всегда в reopen: неверный pid, нет прав на kill, или unit не reload-ится. Смотрите journal/cron-лог запуска logrotate.
Краткий чеклист
- Правила сервиса в
/etc/logrotate.d/, не раздувайте только global conf. - После rename файла нужен reopen (signal, reload, flush-logs).
createс корректными owner/mode, иначе сервис не сможет писать.- Для шумных логов: daily + size как страховка, не только weekly.
- Перед боем:
logrotate -d, потом точечный-f -v.
Logrotate не заменяет централизованный сбор логов, но на одном хосте это базовый гигиенический слой: диск не кончается, grep по вчерашнему access.log остаётся осмысленным.
