Log Rotation — це механізм автоматичного керування файлами логів, який запобігає переповненню диска за рахунок архівації, стиснення та видалення старих записів. У мобільних застосунках логи накопичуються на пристрої користувача, і без ротації вони можуть зайняти гігабайти пам'яті за кілька тижнів використання. За даними Redis Documentation, коректне налаштування log rotation знижує ризик відмови системи через заповнений диск на 99% порівняно з безконтрольним зростанням логів. Основні стратегії ротації: за розміром файлу, за часом та за кількістю файлів — кожна вибирається залежно від сценарію використання: logrotate у Linux, CocoaLumberjack на iOS і Timber на Android підтримують усі три підходи.
Головне
Log Rotation — це процес періодичної зміни активного файлу лога на новий з одночасною архівацією, стисненням або видаленням старого. Без ротації один файл лога зростає нескінченно, поки не заповнить весь розділ диска, що призводить до відмови застосунку та втрати даних.
Типовий сценарій: застосунок пише логи у файл app.log. Коли app.log досягає 100 МБ, система перейменовує його в app.log.1, стискає в app.log.1.gz і створює новий порожній app.log. При наступному заповненні app.log.1 стає app.log.2, app.log.1.gz — app.log.2.gz, а старий app.log.2.gz видаляється. Цей механізм називається ротацією з keep count — кількість архівних копій фіксована.
За даними Splunk (2023), неправильна конфігурація ротації — причина 40% інцидентів, пов'язаних із заповненням диска на серверах застосунків. Для мобільних пристроїв ротація ще критичніша, оскільки користувач не може і не повинен керувати логами вручну.
Log Rotation підтримує три базові стратегії, які можна комбінувати. Вибір стратегії залежить від типу застосунку: серверні системи частіше використовують ротацію за часом, мобільні — за розміром, вбудовані — за кількістю файлів.
| Стратегія | Тригер | Коли використовувати |
|---|---|---|
| За розміром | Файл досяг N байт | Високонавантажені системи з непередбачуваним об'ємом логів |
| За часом | Минуло N годин/днів | Щоденні дампи, вимоги відповідності |
| За кількістю файлів | Створено N файлів | Мобільні пристрої з обмеженим дисковим простором |
Ротація за розміром гарантує, що жоден файл лога не перевищує заданий ліміт. Ліміт вибирається виходячи з доступного дискового простору та частоти логування. Для сервера типовий ліміт — 100–500 МБ на файл, для мобільного пристрою — 1–10 МБ. Якщо застосунок логує агресивно, ліміт потрібно знижувати, інакше ротація відбуватиметься кожні кілька хвилин.
Ротація за часом незалежна від об'єму логів — файл змінюється строго за розкладом. Зручна для систем, де логи повинні зберігатися фіксовану кількість днів: щоденна ротація з keep count = 30 означає 30 днів зберігання. Недолік — один файл може вирости до гігабайта за день при інтенсивному навантаженні.
logrotate — стандартна утиліта Linux для автоматичної ротації логів. Вона запускається по cron і обробляє конфігураційні файли з /etc/logrotate.d/. Кожен сервіс (nginx, postgresql, застосунок) створює свій конфіг із зазначенням шляхів до логів, стратегії ротації та дій після ротації.
# /etc/logrotate.d/myapp — ротація логів застосунку
/var/log/myapp/*.log {
daily
rotate 7
compress
delaycompress
missingok
notifempty
create 0640 www-data www-data
postrotate
kill -HUP $(cat /var/run/myapp.pid)
endscript
}
Цей конфіг ротує логи щоденно, зберігає 7 архівних копій, стискає старі файли gzip (крім останнього — delaycompress), не видає помилку якщо логів немає (missingok), не ротує порожні файли (notifempty) і перестворює файл з правами 0640. Після ротації надсилає HUP-сигнал процесу застосунку через postrotate-скрипт.
size — ротація при досягненні розміру (size 100M). rotate — кількість архівних копій (rotate 7). compress — стиснення gzip. dateext — додавання дати в ім'я файлу замість порядкового номера. sharedscripts — виконання postrotate один раз для всіх файлів, а не для кожного окремо. maxage — видалення архівів старших N днів.
На мобільних пристроях Log Rotation критична, тому що користувач не керує файловою системою і не очікує, що застосунок займе гігабайти логами. iOS та Android мають вбудовані механізми: os_log на iOS використовує кільцевий буфер фіксованого розміру (ротація за перезаписом), Android Logcat має обмежений буфер в ядрі.
Для кастомних файлових логів на iOS використовується CocoaLumberjack з класом DDFileLogger, який підтримує ротацію за розміром і за часом. На Android — Logback або самописні реалізації через RollingFileAppender. Обидва інструменти дозволяють задати максимальний розмір файлу та кількість архівів.
// CocoaLumberjack — файлова ротація на iOS
import CocoaLumberjack
let fileLogger = DDFileLogger()
fileLogger.maximumFileSize = 1024 * 1024 // 1 МБ
fileLogger.logFileManager.maximumNumberOfLogFiles = 5
DDLog.add(fileLogger)
iOS: os_log не потребує ротації — повідомлення перезаписуються в кільцевому буфері. Але якщо застосунок пише кастомні файлові логи (наприклад, для налагодження або для відправки на сервер), ротацію потрібно налаштовувати вручну. CocoaLumberjack — стандартний вибір для iOS-команд, він автоматично стискає архіви в .gz і видаляє старі файли при перевищенні ліміту.
Android не обмежує застосунок у записі логів у власну директорію. Якщо розробник пише debug-логи у файл без ротації, за місяць активного використання вони можуть зайняти 500 МБ — 1 ГБ. Користувач виявить проблему коли система покаже попередження про нестачу місця і видалить застосунок. Logback з RollingFileAppender вирішує цю проблему: ліміт 5 МБ з 3 архівами гарантує, що логи ніколи не займуть більше 20 МБ.
Нижче наведено приклади налаштування ротації логів на обох платформах. На iOS використовується CocoaLumberjack, на Android — Logback з конфігурацією через XML.
// Logback на Android — конфігурація ротації в logback.xml
// Розмір файлу 5МБ, 3 архівні копії
@file:Suppress("unused")
// У logback.xml:
// <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
// <file>${DATA_DIR}/logs/app.log</file>
// <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
// <fileNamePattern>app.%i.log.gz</fileNamePattern>
// <minIndex>1</minIndex>
// <maxIndex>3</maxIndex>
// </rollingPolicy>
// <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
// <maxFileSize>5MB</maxFileSize>
// </triggeringPolicy>
// </appender>
CocoaLumberjack на iOS підтримує не тільки ротацію за розміром, а й видалення старих логів за датою за допомогою logFileManager.maximumLogFiles. Якщо задати maximumLogFiles = 0, обмеження знімається — логи будуть накопичуватися нескінченно, що небезпечно для production.
// Кастомна ротація з перевіркою загального об'єму
class SizeAwareLogger {
let maxTotalSize: Int64 = 20 * 1024 * 1024
func enforceQuota(at logDirectory: URL) {
let files = (try? FileManager.default
.contentsOfDirectory(
at: logDirectory,
includingPropertiesForKeys: [.fileSize]
)) ?? []
let total = files.reduce(0) {
$0 + (try? $1.resourceValues(forKeys: [.fileSize])
.fileSize).map(Int64.init) ?? 0
}
if total > maxTotalSize {
// Видаляємо найстаріший файл
files.sorted { $0.path < $1.path }.first.map {
try? FileManager.default.removeItem(at: $0)
}
}
}
}
Log Rotation — це не тільки автоматична архівація, а й індикатор здоров'я системи. Якщо логи ротуються занадто часто (кожні кілька хвилин), це сигнал про надмірне логування або про помилку в циклічному логуванні помилок (error log loop). Налаштуйте оповіщення на частоту ротації: більше 10 ротацій на годину — привід для перевірки.
Системи моніторингу (Prometheus, Grafana, Datadog) можуть відстежувати метрики ротації через експортери файлової системи. Prometheus node_exporter надає метрики розміру файлів та часу їх модифікації. На мобільних пристроях моніторинг ротації зазвичай вбудований в SDK: CocoaLumberjack логує подію ротації через DDLog, а Logback надсилає статус через appender.
Оповіщення: якщо архівів стало більше очікуваного (rotate count перевищив ліміт) або загальний об'єм логів перевищив квоту — система повинна сповістити адміністратора. Для серверів стандартний поріг — 80% від розміру розділу, для мобільних пристроїв — оповіщення при перевищенні 50 МБ на застосунок.
Часті запитання
Для серверів — 100–500 МБ, для мобільних застосунків — 1–10 МБ. Занадто маленький ліміт (менше 1 МБ) викликає часту ротацію та зайві операції введення-виведення. Занадто великий (більше 500 МБ) збільшує час відкриття та пошуку у файлі.
Для продакшену — мінімум 7 днів (щоденна ротація) або 3–5 архівів (ротація за розміром). Для compliance-вимог — 30–90 днів, але тоді використовуйте окреме сховище зі стисненням і retention policy, а не ротацію на тому ж розділі.
logrotate — Linux-утиліта, на iOS та Android вона недоступна. На мобільних пристроях ротацію реалізують бібліотеки: CocoaLumberjack для iOS та Logback для Android. Вони не потребують root-доступу і працюють у sandbox-середовищі застосунку.
Перевірте, чи немає циклічного логування — коли обробка помилки сама генерує нову помилку. Додайте захист: лічильник повторних логувань одного типу з порогом (не більше 100 однакових повідомлень на хвилину) та тимчасовим блокуванням після перевищення.
Не обов'язково, але рекомендується. gzip стискає текстові логи в 10–20 разів без втрати даних. На мобільних пристроях стиснення знижує займане місце з 50 МБ до 3–5 МБ. Єдиний мінус — архів не можна прочитати без розпакування, але для аналізу зазвичай потрібен тільки поточний файл.
Підсумки
Ми розробимо мобільний застосунок під ключ
IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також