← Весь справочник

logrotate

Ротация логов — переименовать, сжать, удалить старые и дать службе начать новый файл

logrotate не работает постоянно: его запускают по расписанию (cron или таймер systemd, обычно раз в сутки). При каждом запуске он читает конфиги, решает, какие логи пора «повернуть», и делает это: app.log → app.log.1 → app.log.2.gz…, лишние старые копии удаляет, а для службы создаёт новый пустой файл.

Синтаксис

logrotate [опции] конфиг

Главный конфиг — /etc/logrotate.conf: в нём глобальные настройки и строка include /etc/logrotate.d. Правила для отдельных программ лежат в /etc/logrotate.d/<имя>. Ежедневный запуск — /etc/cron.daily/logrotate (на системах с systemd — logrotate.timer).

Формат правила:

/var/log/myapp/*.log {
    daily
    rotate 7
    compress
    missingok
    notifempty
}

Сначала один или несколько путей (можно шаблоны), затем в фигурных скобках директивы — по одной на строку. Директивы вне скобок задают значения по умолчанию для правил ниже.

Опции командной строки

ОпцияЧто делает
-dотладка: ничего не делает, только печатает, что было бы сделано (включает -v)
-vподробно печатать, что происходит
-fротировать принудительно, даже если по расписанию ещё рано
-s файлсвой файл состояния вместо /var/lib/logrotate/status
-l файлписать лог работы в файл (или syslog)
-m командачем отправлять почту (для mail)

Когда ротировать

ДирективаЧто значит
daily / weekly / monthly / yearlyпо времени с прошлой ротации
hourlyраз в час — только если сам logrotate запускается каждый час
size 100Mкогда файл больше размера (время не учитывается); единицы k, M, G
minsize 1Mпо времени, но только если файл не меньше размера
maxsize 500Mпо времени или раньше, если файл больше размера
notifempty / ifemptyне трогать / трогать пустой файл
missingokнет файла — не ошибка

Сколько хранить и куда

ДирективаЧто значит
rotate 7хранить 7 старых копий; rotate 0 — старые сразу удалять
maxage 30удалять копии старше 30 дней
olddir каталогскладывать копии в другой каталог (на той же ФС)
dateextсуффикс с датой (app.log-20250115) вместо номера
dateformat -%Y%m%d-%sформат даты для dateext
extension .logсохранить расширение в конце: app-20250115.log
start 0с какого номера начинать (по умолчанию 1)

Сжатие

ДирективаЧто значит
compress / nocompressсжимать старые копии (по умолчанию gzip)
delaycompressсжимать со следующего раза: .1 остаётся несжатым, его может дописывать служба
compresscmd, compressext, compressoptionsдругой архиватор: compresscmd /usr/bin/xz, compressext .xz

Как получить новый файл

ДирективаЧто значит
create 0640 user groupпосле переименования создать новый файл с правами и владельцем
nocreateне создавать новый файл
copytruncateскопировать лог и обнулить оригинал — для программ, которые не умеют переоткрывать файл
copyтолько скопировать, оригинал не трогать
su user groupротировать от имени пользователя — нужно, если каталог лога принадлежит не root

Скрипты

ДирективаКогда выполняется
prerotate … endscriptперед ротацией
postrotate … endscriptпосле ротации — обычно здесь сигнал службе переоткрыть лог
firstaction / lastaction … endscriptодин раз до / после обработки всех файлов правила
sharedscriptspre/postrotate — один раз на всё правило, а не на каждый файл шаблона

Скрипты выполняются через /bin/sh.

Примеры

# что будет сделано — без изменений
logrotate -d /etc/logrotate.d/nginx

# проверить свой конфиг принудительно и подробно
logrotate -f -v /etc/logrotate.d/myapp

# прогнать всё, как это делает cron
logrotate /etc/logrotate.conf

# свой конфиг со своим файлом состояния — не трогая системный
logrotate -s /tmp/lr.state /path/to/test.conf

# когда что ротировалось в последний раз
cat /var/lib/logrotate/status

Пример правила для программы, которая по HUP переоткрывает логи:

/var/log/myapp/*.log {
    daily
    rotate 14
    compress
    delaycompress
    missingok
    notifempty
    create 0640 root adm
    sharedscripts
    postrotate
        kill -HUP "$(cat /run/myapp.pid)" 2>/dev/null || true
    endscript
}

Подводные камни

  • Первый запуск ничего не ротирует. Если лога нет в файле состояния, logrotate записывает «ротирован сейчас» и ждёт следующего периода. Для проверки используй -f.
  • -d ничего не делает — это только репетиция. Чтобы увидеть результат, нужен -f (и -v).
  • Без postrotate или copytruncate служба пишет в старый файл. Переименование не меняет открытый дескриптор: процесс продолжит писать в app.log.1, а новый app.log останется пустым.
  • copytruncate может потерять строки, записанные между копированием и обнулением. Если служба умеет переоткрывать логи — лучше create + postrotate.
  • notifempty побеждает даже -f: пустой лог не ротируется.
  • Шаблон * захватит уже ротированные копии. /var/log/app/* превратит app.log.1 в app.log.1.1. Пиши *.log.
  • Конфиг, доступный на запись группе или всем, игнорируется («writable by group or others»). Права — 644, владелец — root.
  • Каталог лога, доступный на запись не-root, тоже пропускается: нужна директива su.
  • Отдельный конфиг не наследует /etc/logrotate.conf. При запуске logrotate мой.conf глобальные create, weekly и прочее не действуют — пиши всё нужное в правиле.
  • Размер пишется без B: size 10M, а не 10MB — иначе ошибка «unknown unit».
  • В контейнере сам по себе он не запустится: ежедневный вызов идёт из cron, а cron надо запустить (service cron start).

См. также

cron · kill · gzip · df-du