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 часов/дней | Ежедневные дампы, compliance-требования |
| По количеству файлов | Создано 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 MB
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
// Размер файла 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, ограничение снимается — логи будут накапливаться бесконечно, что опасно для 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 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также