Ограничение роста логов и проверка освобождения места

Ограничение роста логов и проверка освобождения места

Ограничение роста логов и проверка освобождения места

Если запись в базу данных завершается ошибкой, хотя новых файлов с рабочими данными на диске не появилось, причина нередко в другом: повторяющиеся сообщения об ошибках заполнили системный раздел. Управление объёмом логов — это не периодическое удаление каталогов, а раздельный контроль записи, ротации и хранения с обязательной проверкой фактически освобождённого места. В этой статье на примере Debian 12 рассматриваются системный журнал journal и файловые логи кратковременных задач. Файлы базы данных и существующая схема хранения не изменяются.

Выделенные серверы CloudSFP в стандартной комплектации оснащены двумя NVMe-накопителями по 1TB, каждый с прямым подключением, без аппаратного RAID. Суммарную ёмкость двух дисков нельзя считать свободным местом в файловой системе, где хранятся логи: бюджет нужно определять по фактической точке монтирования. Все приведённые ниже ограничения объёма — примеры настройки, а не параметры сервиса по умолчанию.

1. Найдите источник заполнения и проверьте блоки и inode

После оплаты найдите учётные данные в панели управления и подключитесь по SSH. Если у сервера несколько адресов, используйте первый. Начните с проверок, которые не изменяют данные:

df -hT / /var/log
df -i / /var/log
findmnt -T /var/log
sudo du -xhd1 /var/log
sudo journalctl --disk-usage

df показывает занятое место на уровне файловой системы, а du подсчитывает объём видимых файлов в каталоге. Их результаты не обязаны совпадать. Параметр -x запрещает переход на другие файловые системы и снижает риск включить в подсчёт отдельно смонтированные тома. Если /var/log не находится на отдельном разделе, логи расходуют место корневого раздела вместе с системными файлами.

Если свободного места достаточно, но inode почти закончились, ищите большое количество мелких файлов, а не только самые крупные логи. Зафиксируйте файловую систему, доступное место, использование inode и каталоги с наиболее быстрым ростом, затем определите, что именно нужно обработать. Не записывайте результаты диагностики на раздел, который уже близок к заполнению.

Не удаляйте весь каталог /var/log и не обнуляйте журналы сбоя, пока не сохранили их содержимое. Перед очисткой сохраните данные за нужный промежуток времени и убедитесь, что выбранные файлы не являются данными базы, журналами транзакций или резервными копиями.

2. Задайте отдельный бюджет объёма для journald

Постоянный журнал journal обычно хранится в /var/log/journal. Ограничения удобнее задавать через drop-in-файл: такую настройку проще проверить и отменить, чем изменения, внесённые непосредственно в основной конфигурационный файл. В следующем примере задаются бюджет журнала и резерв свободного места в файловой системе:

sudo install -d -m 0755 /etc/systemd/journald.conf.d
sudo tee /etc/systemd/journald.conf.d/60-capacity.conf >/dev/null <<'EOF'
[Journal]
Storage=persistent
SystemMaxUse=1G
SystemKeepFree=4G
MaxFileSec=1day
EOF

sudo systemd-tmpfiles --create --prefix /var/log/journal
sudo systemctl restart systemd-journald
sudo journalctl --flush
sudo journalctl --disk-usage
sudo systemctl status systemd-journald --no-pager

SystemMaxUse задаёт бюджет места для journal, а SystemKeepFree требует оставлять свободное место в той же файловой системе. Фактическое поведение зависит и от текущего свободного объёма. Эти параметры не ограничивают файлы, которые приложения записывают самостоятельно. MaxFileSec задаёт максимальный временной интервал записей в активном файле, а не срок хранения логов в один день.

Если другая программа одновременно записывает те же сообщения в текстовый лог, ограничение journal не устраняет эту копию. Проверьте весь путь прохождения сообщений и настройте каждый механизм отдельно. Не отключайте службу системного журналирования без предварительной проверки.

Перед очисткой выполните ротацию и проверьте результат

sudo journalctl --rotate
sudo journalctl --vacuum-size=1G
sudo journalctl --disk-usage
df -h /var/log

Операция vacuum удаляет только архивные файлы и не удаляет активные напрямую, поэтому итоговый объём не обязательно будет точно равен указанному значению. Перезапуск journald — часть изменения конфигурации: перед ним проверьте текущее состояние службы, а после убедитесь, что не появились новые ошибки и логи приложений продолжают поступать в journal.

3. Определите, кто отвечает за ротацию файловых логов

Сначала выясните, какой процесс записывает лог, держит ли он файл постоянно открытым и охватывают ли этот путь существующие правила. Один и тот же файл нельзя одновременно обслуживать встроенной ротацией приложения и logrotate. Также не добавляйте широкие шаблоны, дублирующие уже существующие системные правила.

Установите инструменты для проверки:

sudo apt-get update
sudo apt-get install logrotate lsof

Предположим, кратковременная задача при каждом запуске заново открывает /var/log/local-batch/run.log, а после завершения закрывает файл. В этом случае в /etc/logrotate.d/local-batch можно записать:

/var/log/local-batch/run.log {
    daily
    maxsize 100M
    rotate 7
    compress
    delaycompress
    missingok
    notifempty
    create 0640
}

Каталог и исходный лог должны уже существовать, а их владельцы должны соответствовать учётной записи, от которой выполняется задача. Если в create 0640 не указан владелец, сохраняются владелец и группа исходного файла. Если в каталог может писать непривилегированная учётная запись, отдельно оцените необходимость директивы su и права доступа к каталогу: копировать правило без проверки нельзя.

sudo logrotate -d /etc/logrotate.conf
systemctl list-timers --all --no-pager

Параметр -d только показывает результат пробного прогона и не выполняет ротацию. Проверьте реальную частоту запуска через таймер или cron: maxsize проверяется только при вызове logrotate и не является жёстким ограничением, действующим в реальном времени. rotate 7 означает хранение семи архивных файлов, а не обязательно семи дней истории.

Для постоянно работающего процесса нужен поддерживаемый приложением механизм повторного открытия логов. После переименования файла процесс может продолжить запись в старый файл. Не подбирайте сигнал наугад и не используйте copytruncate по умолчанию: между копированием и обнулением возможна потеря записей.

4. Проверьте ротацию и права доступа в отдельном каталоге

Не проверяйте новое правило принудительной ротацией всей глобальной конфигурации. Следующий тест использует отдельный каталог и файл состояния, не затрагивая рабочие логи:

umask 077
test_dir=$(mktemp -d)
printf '%0200d\n' $(seq 1 20) >"$test_dir/run.log"

cat >"$test_dir/rules" <<EOF
"$test_dir/run.log" {
    size 1k
    rotate 2
    create 0640
}
EOF

logrotate -d -s "$test_dir/state" "$test_dir/rules"
logrotate -s "$test_dir/state" "$test_dir/rules"
ls -l "$test_dir"
printf 'after rotation\n' >>"$test_dir/run.log"
cat "$test_dir/run.log"

В результате должны появиться архивный файл и новый активный файл с ожидаемыми правами доступа. Последняя операция записи подтверждает только возможность заново открыть файл по его пути. Она не доказывает, что постоянно работающее приложение автоматически переключится на новый файл. Для проверки в рабочей среде нужно также запустить реальную задачу, получить узнаваемую запись и убедиться, что она появилась в новом активном файле.

Оставьте тестовый каталог для проверки результатов и удалите его после подтверждения. Рабочие правила по-прежнему должны использовать штатный системный файл состояния. Не допускайте одновременного ручного запуска и запуска по расписанию и не используйте два файла состояния для постоянного управления одним и тем же логом.

5. Подтвердите освобождение места и устраните повторяющиеся ошибки

Если после удаления файлов свободного места не стало больше, сначала проверьте файлы, которые процессы всё ещё держат открытыми:

sudo lsof +L1
df -h /var/log
df -i /var/log
sudo du -xhd1 /var/log

lsof +L1 выводит открытые файлы с числом ссылок меньше единицы. Оценивайте результаты по пути, размеру и процессу: не каждый такой файл является логом. Определив нужный файл, выполните повторное открытие логов по документации приложения, при необходимости перезапустите соответствующую службу, затем снова проверьте df. Не пытайтесь принудительно освободить место завершением неизвестных процессов или записью в их файловые дескрипторы.

При проверке зафиксируйте как минимум четыре результата: новые записи поступают в активный файл, число архивов соответствует правилу, учётная запись может продолжать запись, а свободное место в файловой системе не продолжает аномально сокращаться. Если сообщения об ошибках по-прежнему массово повторяются, устраните их источник — повторные попытки неудачных операций, некорректные запросы или отладочный вывод. Ротация не заменяет устранение неисправности.

Бюджет объёма также не гарантирует сохранение истории за фиксированный промежуток времени. В периоды пиковой нагрузки логи растут быстрее, и при том же бюджете старые записи удаляются раньше. Для данных, которые нужно хранить долго, отдельно спроектируйте передачу, контроль доступа и резервное копирование, а затем проверьте возможность чтения. Локальная ротация ограничивает только объём логов на сервере и не выполняет роль резервного копирования.

Часто задаваемые вопросы

Ограничивает ли journalctl vacuum размер всех журналов сразу?

Нет. Vacuum удаляет архивные журналы, но не активные файлы. Сначала выполнить journalctl --rotate, затем journalctl --vacuum-size=1G и проверить объём через journalctl --disk-usage и df.

Почему после удаления лога свободное место в df не увеличилось?

Процесс может удерживать удалённый файл открытым. Команда sudo lsof +L1 покажет размер и процесс. Далее следует использовать поддерживаемое приложением переоткрытие логов либо перезапустить соответствующую службу.

Выделенный физический сервер AMD EPYC 7543P — от $441.4 в месяц