До основного вмісту

Logrotate: автоматична ротація логів у Linux

VDS / VPS · 15.02.2026 · 5 хв читання
Ілюстрація до статті «Logrotate: автоматична ротація логів у Linux»

Logrotate — стандартний інструмент Linux для керування лог-файлами. Автоматично архівує, стискає та видаляє старі логи за розкладом.

Як працює logrotate

  • Запускається через cron (/etc/cron.daily/logrotate)
  • Читає конфіги з /etc/logrotate.conf та /etc/logrotate.d/
  • Для кожного логу застосовує правила: rotate, compress, delete

Конфіг для Nginx

sudo nano /etc/logrotate.d/nginx
/var/log/nginx/*.log {
    daily
    missingok
    rotate 14
    compress
    delaycompress
    notifempty
    create 0640 www-data adm
    sharedscripts
    postrotate
        nginx -s reopen
    endscript
}

Конфіг для вашого застосунку

sudo nano /etc/logrotate.d/myapp
/var/www/myapp/logs/*.log {
    weekly
    rotate 8
    compress
    delaycompress
    missingok
    notifempty
    create 0644 www-data www-data
}

Тестування та запуск

# Тест без реального виконання
sudo logrotate -d /etc/logrotate.d/nginx

# Примусовий запуск
sudo logrotate -f /etc/logrotate.conf

# Перевірити статус
sudo cat /var/lib/logrotate/status
ДирективаЗначення
daily/weekly/monthlyЧастота ротації
rotate NЗберігати N архівів
compressСтискати gzip
missingokНе видавати помилку, якщо файл відсутній
✅ Перевіряйте вільне місце командою df -h. Якщо /var заповнений — запустіть logrotate -f /etc/logrotate.conf примусово.

Розбір типових помилок

Помилка error: skipping "/var/log/nginx/access.log" because parent directory has insecure permissions зʼявляється, якщо каталог з логами доступний на запис групі чи всім — logrotate з міркувань безпеки відмовляється працювати з такими шляхами, щоб хтось не підмінив лог символьним посиланням на системний файл.

error: skipping "/var/log/nginx/access.log" because parent directory has insecure permissions
(It's world writable or writable by group which is not "root")

Рішення — виставити права каталогу chmod 755 /var/log/nginx, а не розширювати список довірених груп у /etc/logrotate.conf: це діра в безпеці, а не обхід бага. Прапорець su у правилі (su www-data www-data) іноді використовують замість виправлення прав, але він лише змінює користувача, від імені якого logrotate виконує ротацію, і не скасовує перевірку безпеки самого каталогу.

Після налаштування лог все одно росте нескінченно, хоча правило начебто правильне. Часта причина — процес тримає старий файловий дескриптор відкритим навіть після ротації: без postrotate зі свіжим сигналом переоткриття лог-файлу (nginx -s reopen, systemctl reload myapp) застосунок продовжує писати у вже перейменований і покинутий файл access.log.1, а новий access.log лишається порожнім.

directory vs default: де шукати проблему

СимптомЙмовірна причинаПеревірка
Правило не спрацьовує взагаліСинтаксична помилка в конфігуlogrotate -d покаже помилку парсингу
Файл ротується, але не стискаєтьсяДиректива compress відсутня або закоментованаПеревірити підсумковий конфіг порядково
Новий файл порожній, старий ростеЗастосунок не переоткрив дескрипторПеревірити наявність і вміст postrotate
«insecure permissions»Права каталогу логів занадто відкритіls -ld /var/log/назва-каталогу

Коли logrotate не підходить

  • Застосунок уже пише логи через journald — тоді ротацією і зберіганням займається journalctl --vacuum-size/--vacuum-time, а не logrotate, дублювати обидва механізми надлишково.
  • Потрібна централізована агрегація логів з кількох серверів і повнотекстовий пошук — logrotate лише локально керує файлами, для агрегації потрібен стек на кшталт Grafana Loki.
  • Логи мають ротуватися за розміром у реальному часі, а не раз на добу за кроном — logrotate запускається за розкладом cron, а не стежить за файлом безперервно; для миттєвої ротації за розміром потрібен інструмент на кшталт logrotate з частішим запуском або застосунок з власною ротацією.
  • Контейнеризований застосунок пише логи в stdout, а не у файл — ротацією stdout-логів керує сам рушій контейнерів через драйвер логування (json-file з лімітом розміру), а не logrotate всередині контейнера.

Перевірка результату

  1. Перевірте синтаксис без реальної ротації: logrotate -d /etc/logrotate.d/nginx — у виводі не повинно бути рядків з error.
  2. Примусово виконайте ротацію: logrotate -f /etc/logrotate.d/nginx і переконайтесь, що зʼявився файл на кшталт access.log.1.gz.
  3. Перевірте, що застосунок продовжує писати в новий файл, а не в старий: tail -f /var/log/nginx/access.log має показувати нові запити одразу після ротації.
  4. Перевірте статус останнього запуску: cat /var/lib/logrotate/status | grep nginx має показувати сьогоднішню дату.

Звільнення місця на диску від уже накопичених старих логів розібрано окремо в статті про logrotate на VPS. Для логів systemd-сервісів без файлів на диску див. статтю про journalctl і rsyslog.

Перевірити наявні правила

# Переглянути всі конфіги logrotate
ls /etc/logrotate.d/

# Протестувати без реальної ротації
sudo logrotate --debug /etc/logrotate.conf

Створити правило для свого застосунку

# /etc/logrotate.d/myapp
/var/log/myapp/*.log {
    daily           # Ротація щодня
    missingok       # Не видавати помилку, якщо файл відсутній
    rotate 14       # Зберігати 14 архівів
    compress        # Стиснути gzip
    delaycompress   # Не стискати останній архів
    notifempty      # Не ротувати порожні файли
    create 0640 www-data www-data  # Права нового файлу
    postrotate
        systemctl reload nginx > /dev/null 2>&1 || true
    endscript
}

Параметри logrotate

ПараметрОпис
daily/weekly/monthlyПеріод ротації
rotate NКількість архівів
size 100MРотація за розміром
compressСтиснути gzip
maxage 30Видаляти архіви старші 30 днів
sharedscriptspostrotate виконується один раз

Примусова ротація прямо зараз

sudo logrotate --force /etc/logrotate.d/myapp
✅ Logrotate запускається щодня через cron (/etc/cron.daily/logrotate). Зазвичай нічого додатково налаштовувати не потрібно.

Звільнення місця від старих логів

# Знайти великі лог-файли
sudo find /var/log -name "*.log" -size +100M

# Очистити файл без видалення (процес продовжує писати)
sudo truncate -s 0 /var/log/nginx/access.log

# Або через journald
sudo journalctl --vacuum-size=500M

du проти df: як швидко зрозуміти, де місце

СимптомКоманда для діагностикиЩо показує
df бачить менше вільного місця, ніж dulsof +L1Видалені, але все ще відкриті файли
Незрозуміло, який каталог найважчийdu -h --max-depth=1 /var/log | sort -rhРозмір кожного підкаталогу логів
Логи ростуть швидше, ніж очікувалосяwatch -n 5 'du -sh /var/log/nginx'Швидкість приросту в реальному часі

Коли звичайної ротації мало

  • Диск уже заповнений вщент прямо зараз, а не ротація потрібна на майбутнє — logrotate --force не допоможе миттєво, якщо винні відкриті видалені файли; потрібно спершу перезапустити процеси, що їх тримають.
  • Логів накопичується більше, ніж дозволяє тримати диск навіть зі стисненням — потрібне винесення логів на окремий том, в обʼєктне сховище або в централізовану систему на кшталт Grafana Loki, а не агресивніша ротація на тому самому диску.
  • Потрібно знайти конкретну причину аномального росту логів, а не просто звільнити місце — це вже задача аналізу самих логів на помилки і підозрілий трафік, а не ротації.
Чи була стаття корисною?
← Назад до бази знань Поставити питання підтримці