Настройка автоматического удаления старых логов с logrotate на Ubuntu 24.04

Настройка автоматического удаления старых логов с logrotate на Ubuntu 24.04

Что делать, чтобы логи не заполнили весь диск? Рассказываем, как настроить ротацию логов с logrotate на Ubuntu 24.04, также приводим примеры настроек для веб-сервера, базы данных и приложения, которому не подходит ротация по времени.

Введение

В Ubuntu 24.04 логи системных и сервисных компонентов хранятся в /var/log/ и без ротации они со временем заполняют диск. Чтобы этого не происходило, нужно настроить автоматическую очистку старых логов. В системе за это отвечает logrotate — утилита, которая по заданным правилам архивирует, сжимает и удаляет журналы.

Аренда VPS/VDS — от ₽219/месяц

Почему выбирают VPS от AdminVPS:

✓ Дешевле физического сервера

✓ Более гибкий и мощный, чем обычный хостинг

✓ Бесплатная защита от DDoS и техподдержка 24/7

✓ Масштабируется под любые задачи

Виртуальный сервер VPS/VDS — ваш личный сервер для сайтов, магазинов, ботов и других проектов.

Как работает logrotate

logrotate — это стандартная утилита в Ubuntu 24.04, которая позволяет задать правила ротации для любых лог-файлов: системных, сервисных или кастомных. Её задача — регулярно проверять состояние журналов и, если выполняются заданные условия (размер, возраст, количество копий и т. д.), выполнять действия: переименование, сжатие, удаление и создание нового файла.

По умолчанию logrotate запускается ежедневно через системный cron-джоб /etc/cron.daily/logrotate. Этот скрипт может вызываться через systemd timer или напрямую cron, в зависимости от конфигурации.

При запуске logrotate:

  • проверяет файлы, указанные в конфигурации;
  • переименовывает текущий лог-файл, добавляя к имени постфикс (например, .1, .gz, .20250730);
  • создаёт новый файл с тем же именем, чтобы приложение продолжило писать в него;
  • сжимает старый файл в gzip (если указано compress);
  • удаляет архивы, превышающие лимит по количеству (rotate) или по возрасту (maxage);
  • выполняет скрипты до и после ротации (если заданы prerotate, postrotate, firstaction, lastaction).

Главный конфигурационный файл — /etc/logrotate.conf. Этот файл содержит глобальные параметры и директивы, применимые ко всем логам, если в других местах не указано иное. Пример содержимого:

weekly
rotate 4
create
compress
include /etc/logrotate.d

Здесь: 

  • weekly — ротация раз в неделю; 
  • rotate 4 — хранить 4 архивных копии; 
  • create — создавать новый пустой файл после ротации; 
  • compress — использовать gzip для старых логов;
  • include /etc/logrotate.d — подключить дополнительные правила из этой директории. 

/etc/logrotate.d/ — каталог с настройками ротации логов конкретных приложений, например: 

  • /etc/logrotate.d/nginx
  • /etc/logrotate.d/mysql-server
  • /etc/logrotate.d/rsyslog

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

logrotate ведёт внутреннюю базу с временными метками — по умолчанию это файл /var/lib/logrotate-state. В нём хранятся последние даты ротации для каждого файла, что позволяет logrotate не дублировать работу и не трогать файлы чаще, чем нужно. Если этот файл удалить — при следующем запуске logrotate посчитает, что ни один лог ещё не ротировался, и выполнит ротацию для всех сразу (полезно, если нужно немедленно применить новые настройки).

Если в правилах указано compress, старые логи сжимаются через gzip сразу после ротации. Чтобы контролировать степень и время сжатия есть вспомогательные директивы:

  • delaycompress — откладывает сжатие на один цикл ротации. То есть, при первой ротации файл переименовывается, но не сжимается (удобно, если приложение не сразу переключается на новый файл);
  • compresscmd — позволяет указать другой метод сжатия (по умолчанию gzip, можно задать xz, zstd, bzip2).

Примеры настройки ротации логов

Ротация логов веб-сервера Nginx

logrotate по умолчанию умеет ротировать логи Nginx — при установке nginx-common создаётся файл /etc/logrotate.d/nginx. Но стоит проверить, актуальны ли параметры и, если нужно, адаптировать их под себя:

/var/log/nginx/*.log {
    daily
    rotate 14
    compress
    delaycompress
    missingok
    notifempty
    create 0640 www-data adm
    postrotate
        systemctl reload nginx
    endscript
}

В этом конфиге:

  • /var/log/nginx/*.log — указывает шаблон логов, которые нужно ротировать. В стандартной установке это access.log и error.log, но могут быть и другие — например, логи виртуальных хостов.
  • daily — ежедневная ротация. Это актуально, если трафик стабильный и лог-файлы могут быстро разрастаться. Если логов мало, можно заменить на weekly — ротация раз в неделю. 
  • rotate 14 — хранить 14 архивных копий. В связке с daily это две недели логов, при weekly — это почти 4 месяца.
  • compress — сжатие архивных файлов через gzip
  • delaycompress — сжимать не текущую ротацию, а предыдущую. Это важно для совместимости: приложения могут временно продолжать писать в уже переименованный файл, а не переключаться сразу на новый.
  • missingok — не считать ошибкой, если лог-файл отсутствует.
  • notifempty — не выполнять ротацию, если файл пуст. 
  • create 0640 www-data adm — после ротации создать новый пустой файл с такими параметрами:
    • 0640 — права доступа (владелец может читать и писать, группа — только читать); 
    • www-data — владелец файла (веб-сервер);
    • adm — группа, которая может просматривать логи.

Это важный параметр: если не задать create, лог-файл не будет пересоздан, и Nginx не сможет в него писать. А если задать неправильные права — веб-сервер может получить ошибку Permission denied.

  • postrotate … endscript — блок postrotate исполняется после ротации. Здесь вызывается systemctl reload nginx — команда, которая заставляет Nginx перечитать конфигурацию и заново открыть лог-файлы. Если этого не сделать, Nginx продолжит писать в удалённый файл, открытый по файловому дескриптору, и ротация окажется бессмысленной.

Ротация логов PostgreSQL

PostgreSQL может быстро раздувать логи, особенно если активен SQL-логгинг или включено логирование медленных запросов.

Пример конфигурации для PostgreSQL 16:

/var/log/postgresql/*.log {
    weekly
    rotate 8
    compress
    sharedscripts
    postrotate
        pg_ctlcluster 16 main reload
    endscript
}

Здесь:

  • sharedscripts logrotate запускает postrotate один раз для всех файлов из этого блока, а не для каждого по отдельности;
  • postrotate … endscript — команда pg_ctlcluster перезапускает лог-файл, не затрагивая саму работу базы, 16 — версия PostgreSQL, а main — имя кластера (можно посмотреть через pg_lsclusters).

Ротация логов кастомных приложений

Собственные сервисы, особенно те, которые много пишут в STDOUT/STDERR или ведут логи по собственному формату, не всегда поддаются ротации по времени. В таких случаях удобно ротировать по размеру:

/opt/myapp/logs/*.log {
    size 100M
    rotate 5
    compress
    dateext
}

Параметры:

  • size 100M — ротация файлов, достигших размера 100 мегабайт;
  • dateext — добавляет дату в имя архива, например: app.log-20250730.gz. Это упрощает отладку и автоматический разбор логов по времени.

Если приложение не реагирует на ротацию (например, продолжает писать в старый файл), нужно либо добавить postrotate с systemctl reload myapp, либо использовать директиву copytruncate, которая копирует содержимое текущего лог-файла в архив и очищает исходный файл, а приложение при этом продолжает писать в тот же файл без перерыва. Однако использование copytruncate связано с риском: возможна потеря данных, если приложение продолжает писать в момент копирования.

Параметры logrotate

logrotate даёт возможность гибко управлять поведением ротации с помощью дополнительных директив:

  • maxage — удаляет архивные лог-файлы по их возрасту, независимо от значения rotate. Например maxage 30 удалит все логи старше 30 дней. Если указаны оба параметра — rotate и maxage — будет применён более строгий.
  • minsize — не ротировать лог-файл, если его размер меньше указанного. Удобно для случаев, когда периодическая ротация по дате не имеет смысла, если файл почти не содержит данных. Часто используется совместно с daily или weekly, чтобы избежать создания пустых архивов.
  • dateformat, например dateformat -%Y%m%d, — используется вместе с директивой dateext, чтобы задать формат даты, добавляемой к имени архивного лог-файла. В этом примере архив может называться access.log-20250730.gz. Поддерживаются все стандартные элементы strftime:
    • %Y — год;
    • %m — месяц;
    • %d — день;
    • %H, %M, %S — часы, минуты, секунды (если нужно точное время).
  • su (su appuser appgroup) — указывает, под каким пользователем и группой запускать ротацию для данного блока. Это критично в ситуациях, когда лог-файлы принадлежат не root, а какому-либо приложению (например, nginx, postgres, myapp) и имеют ограничения по доступу. Без su logrotate может не иметь прав на создание или изменение лог-файла после ротации, что приведёт к ошибкам.
  • compresscmd / uncompresscmd — позволяют задать альтернативные утилиты для сжатия. По умолчанию используется gzip, но можно заменить на xz, zstd или bzip2, если нужны другие алгоритмы:
compresscmd /usr/bin/xz
uncompresscmd /usr/bin/unxz
  • extension — задаёт расширение архивных файлов. Полезно, если сжатие отключено, но вы хотите отличать архивы по имени.
extension .bak
  • ifempty — ротировать даже пустые логи (например, в тестовых средах).
  • notifempty — не трогать пустые файлы.
  • firstaction / lastaction — позволяют запускать скрипты один раз до/после всей серии ротаций. Например:
firstaction
    echo "Ротация началась: $(date)" >> /var/log/rotate.log
endscript

Это удобнее, чем писать то же самое в каждый postrotate, особенно если обрабатывается сразу несколько файлов в одном блоке.

Проверка работоспособности и диагностика проблем

Перед тем как применять изменения в продакшене, проверьте конфиг на корректность. Это делается через ключ -d (dry-run), который только показывает, что будет выполнено, без реального запуска:

sudo logrotate -d /etc/logrotate.d/nginx

Команда выведет на экран, какие файлы будут ротироваться, что с ними произойдёт, какие команды будут вызваны (postrotate, compress и т. д.).

Чтобы выполнить ротацию принудительно, без ожидания следующего запуска cron, добавьте ключ -f (force):

sudo logrotate -f /etc/logrotate.conf

Можно указать конкретный файл:

sudo logrotate -f /etc/logrotate.d/nginx

Обратите внимание, что после -f создаются новые архивы и обновляется статус-файл (/var/lib/logrotate-state).

Чтобы найти «тяжёлые» логи, выполните:

sudo ncdu /var/log/

ncdu отображает дерево директорий в интерактивном виде, и вы сможете легко определить, какие файлы самые большие и какие директории переполнены.

Альтернативный способ через du:

sudo du -sh /var/log/* | sort -hr | head -20

Команда выведет 20 самых объёмных поддиректорий и файлов в /var/log/.

Для глубокого анализа полезно посмотреть внутренний статус-файл logrotate:

sudo cat /var/lib/logrotate-state

В этом файле хранятся последние даты ротации по каждому лог-файлу. Если нужного файла в списке нет — logrotate о нём не знает. Если есть, но дата старая — значит, ротация не запускалась и нужно искать причину.

Читайте в блоге:

Loading spinner
0 Комментарий
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии

Нужен VPS сервер?

Арендуйте мощный VPS сервер для ваших проектов! Быстрая настройка, высокая производительность и надежная поддержка 24/7. Начните прямо сейчас!

Что будем искать? Например,VPS-сервер

Мы в социальных сетях