Логи растут незаметно: сервис пишет мегабайты в час, и однажды раздел заполняется целиком. Logrotate решает задачу ротации — сжатия, удаления и запуска команд после смены файла. Разберём, как настроить правила для реальных сервисов, избежать потери данных и убедиться, что ротация действительно работает.

Как устроен logrotate

Конфигурация лежит в /etc/logrotate.conf и /etc/logrotate.d/. Каждый пакет может добавить свой файл: Nginx, PostgreSQL, Docker и другие. Основные директивы задают период, объём, число копий и команды после ротации.

# базовая структура правила
/var/log/nginx/*.log {
    daily
    missingok
    rotate 14
    compress
    delaycompress
    notifempty
    sharedscripts
    postrotate
        systemctl reload nginx > /dev/null 2>&1 || true
    endscript
}

Опция missingok не считает отсутствие файла ошибкой, delaycompress откладывает сжатие на один цикл — это спасает сервисы, которые ещё пишут в старый файл.

Как запускается ротация

В десктопных дистрибутивах работает systemd-таймер, на серверах — cron-задание. Проверьте и то и другое: часто ротация «не работает» просто потому, что задание отключено.

# какое задание отвечает
systemctl list-timers | grep -i logrotate
cat /etc/cron.daily/logrotate 2>/dev/null
# ручной запуск с отладкой — ничего не меняет, только показывает план
sudo logrotate -d /etc/logrotate.conf 2>&1 | tail -40
# фактическое применение
sudo logrotate -v /etc/logrotate.conf 2>&1 | tail -30

Флаг -d безопасен: он показывает, что произошло бы, без записи. Используйте его всегда перед первым запуском нового правила.

Периоды и объём

Daily подходит большинству сервисов. Но для высоконагруженных систем нужен hourly и ограничение по размеру, иначе за сутки файл успевает вырасти до гигабайтов.

# hourly с ограничением размера
/var/log/app/*.log {
    hourly
    rotate 48
    maxsize 100M
    compress
    missingok
}
# проверить время последнего применения
ls -lh --time-style=long-iso /var/log/nginx/ | tail -10

Опция maxsize включает ротацию раньше срока, если файл превысил лимит. Это важнее частоты: размер, а не календарь, создаёт риск.

Команды после ротации

Большинство сервисов в Linux пишут в открытый файловый дескриптор. После переименования дескриптор указывает на старое имя, и записи уходят туда до перезапуска. Сигнал HUP заставляет процесс открыть файл заново.

# типичные postrotate для разных служб
# nginx:  systemctl reload nginx
# rsyslog: kill -HUP $(cat /var/run/rsyslogd.pid 2>/dev/null) 2>/dev/null
# PostgreSQL использует copytruncate — см. ниже

# проверить, что PID-файл существует
ls -l /var/run/rsyslogd.pid /run/nginx.pid 2>/dev/null

copytruncate против postrotate

copytruncate копирует содержимое и обрезает файл на месте, не требуя перезапуска. Он проще, но при копировании возможна потеря записей, пришедших в момент операции.

/var/log/app/*.log {
    daily
    copytruncate
    compress
    rotate 7
}

Используйте copytruncate, когда перезапуск сервиса недопустим, а postrotate — когда важна целостность логов. Для критичных сервисов предпочтительнее postrotate.

Ротация приложения, которое пишет один файл

Если приложение само открывает файл по пути и не умеет перечитывать его, поможет паттерн с датой в имени через внешний скрипт. Но проще научить приложение писать в stdout и собирать логи journald.

# проверить, кто держит файл
sudo lsof +L1 | grep -i log | head
sudo fuser -v /var/log/app/app.log
# направить в journal вместо файла
journalctl -u app | tail -30

Ограничение места под журналы

Параллельно с logrotate ограничьте общий объём: systemd-journald имеет собственные лимиты, а старые сжатые файлы копятся годами.

# текущее использование
journalctl --disk-usage
grep -E "^SystemMaxUse|^SystemMaxFileSize" /etc/systemd/journald.conf
# ограничить
sudo journalctl --vacuum-size=500M
# сжатые логи старше 30 дней
sudo find /var/log -name "*.gz" -mtime +30 -delete
df -h /var/log /

Типичные ошибки

  • Правило не применяется: опечатка в пути или синтаксисе — смотрите вывод logrotate -d.
  • Сервис не перечитывает файл после ротации — логи пишутся в старое имя.
  • Слишком короткий rotate: важные события удаляются до того, как их прочитали.
  • Нет compress: диск заполняется скорее ожидаемого.
  • Логи ротируются на том же разделе, что и данные, — очистка не спасает при общем отказе.
# найти «протекающие» файлы
sudo lsof +L1 2>/dev/null | awk '$7 < 0 {print $1, $9}' | head
# проверить, что правило попало в общий конфиг
sudo logrotate -d /etc/logrotate.conf 2>&1 | grep -A5 "app" | head -20

Логи контейнеров и приложений без файлов

Docker пишет логи в JSON-файлы и не подчиняется logrotate напрямую. Ограничьте их настройками демона, иначе за месяц наберутся десятки гигабайтов.

# /etc/docker/daemon.json
# { "log-driver": "json-file", "log-opts": { "max-size": "50m", "max-file": "5" } }

# проверить текущие настройки логирования контейнера
docker inspect mycontainer --format '{{.HostConfig.LogConfig}}'
# размер логов контейнеров
sudo du -sh /var/lib/docker/containers/*/*-json.log 2>/dev/null | sort -h | tail

После смены конфигурации демон перезапускается, поэтому меняйте её в окно обслуживания. Для приложений, пишущих в файл внутри контейнера, перенаправляйте вывод в stdout — так он попадёт в единый конвейер.

Наблюдение за самой ротацией

Полезно убедиться, что ротация выполняется по расписанию и не пропускает циклы. Если задание пропущено, лог растёт молча.

# когда последний раз выполнялась ротация
grep -i "logrotate" /var/log/syslog | tail -10
ls -lh --time-style=long-iso /var/log/*.1 2>/dev/null | head
# текущие размеры
du -sh /var/log/* 2>/dev/null | sort -h | tail -12
# счётчик свободного места
df -h /var/log /

Добавьте размер /var/log в общий чек-лист мониторинга: ротация, journald и свободное место смотрят на одну проблему с разных сторон.

Итог

Logrotate настраивается правилом на сервис: период, maxsize, сжатие и команда после ротации. Проверяйте правила через logrotate -d, убеждайтесь, что таймер запущен, а сервис перечитывает файл. Дополнительно ограничьте размер journald и регулярно смотрите df -h: ротация работает только тогда, когда её результат виден.

Насколько публикация полезна?

Нажмите на звезду, чтобы оценить!

Средняя оценка 0 / 5. Количество оценок: 0

Оценок пока нет. Поставьте оценку первым.

Поделиться: Telegram ВКонтакте