Log Rotation е механизъм за автоматично управление на лог файлове, който предотвратява препълването на диска чрез архивиране, компресиране и изтриване на стари записи. В мобилните приложения логовете се натрупват на устройството на потребителя и без ротация могат да заемат гигабайти памет само за няколко седмици употреба. Според Redis Documentation, правилното конфигуриране на log rotation намалява риска от отказ на системата поради пълен диск с 99% в сравнение с неконтролирания растеж на логовете. Основните стратегии за ротация: по размер на файла, по време и по брой файлове — всяка се избира в зависимост от сценария на употреба: logrotate в Linux, CocoaLumberjack на iOS и Timber на Android поддържат и трите подхода.
Основни точки
Log Rotation е процес на периодична смяна на активния лог файл с нов, като едновременно с това старият се архивира, компресира или изтрива. Без ротация един лог файл расте безкрайно, докато не запълни целия дисков дял, което води до отказ на приложението и загуба на данни.
Типичен сценарий: приложението записва логове във файла app.log. Когато app.log достигне 100 MB, системата го преименува на 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 MB на файл, за мобилно устройство — 1–10 MB. Ако приложението логва агресивно, лимитът трябва да се намали, в противен случай ротацията ще се случва на всеки няколко минути.
Ротацията по време е независима от обема на логовете — файлът се сменя строго по график. Удобна за системи, където логовете трябва да се съхраняват фиксиран брой дни: ежедневна ротация с 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 MB
fileLogger.logFileManager.maximumNumberOfLogFiles = 5
DDLog.add(fileLogger)
iOS: os_log не изисква ротация — съобщенията се презаписват в цикличния буфер. Но ако приложението записва персонализирани файлови логове (например за отстраняване на грешки или изпращане до сървър), ротацията трябва да се конфигурира ръчно. CocoaLumberjack е стандартният избор за iOS екипи, автоматично компресира архивите в .gz и изтрива стари файлове при превишаване на лимита.
Android не ограничава приложението в записването на логове в собствената му директория. Ако разработчикът записва debug логове във файл без ротация, за месец активно използване те могат да заемат 500 MB — 1 GB. Потребителят ще открие проблема, когато системата покаже предупреждение за недостатъчно пространство и ще изтрие приложението. Logback с RollingFileAppender решава този проблем: лимит от 5 MB с 3 архива гарантира, че логовете никога няма да заемат повече от 20 MB.
По-долу са дадени примери за конфигуриране на ротация на логове на двете платформи. На iOS се използва CocoaLumberjack, на Android — Logback с конфигурация чрез XML.
// Logback на Android — конфигурация на ротация в logback.xml
// Размер на файла 5MB, 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, ограничението се премахва — логовете ще се натрупват безкрайно, което е опасно за продукция.
// Персонализирана ротация с проверка на общия обем
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 MB на приложение.
Често задавани въпроси
За сървъри — 100–500 MB, за мобилни приложения — 1–10 MB. Твърде малкият лимит (под 1 MB) причинява честа ротация и излишни I/O операции. Твърде големият лимит (над 500 MB) увеличава времето за отваряне и търсене във файла.
За продукция — минимум 7 дни (ежедневна ротация) или 3–5 архива (ротация по размер). За изисквания за съответствие — 30–90 дни, но тогава използвайте отделно хранилище с компресия и политика за съхранение, а не ротация на същия дял.
logrotate е Linux помощна програма, недостъпна на iOS и Android. На мобилни устройства ротацията се имплементира от библиотеки: CocoaLumberjack за iOS и Logback за Android. Те не изискват root достъп и работят в sandbox средата на приложението.
Проверете дали има циклично логване — когато обработката на грешка сама генерира нова грешка. Добавете защита: брояч на повторения на логване от един тип с праг (не повече от 100 идентични съобщения в минута) и времево блокиране след превишаване.
Не е задължително, но се препоръчва. gzip компресира текстовите логове 10–20 пъти без загуба на данни. На мобилни устройства компресията намалява заетото пространство от 50 MB до 3–5 MB. Единственият недостатък — архивът не може да се чете без декомпресия, но за анализ обикновено е необходим само текущият файл.
Резюме
Ще разработим мобилно приложение под ключ
IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също