Как уменьшить размер лога без остановки процесса
Что проверяют
Знаете ли вы, как процесс держит открытый файл, и не устроите ли на тестовом стенде ситуацию, когда лог «удалён», а диск по-прежнему забит. Следом часто спрашивают, как вы это проверите и чем copytruncate отличается от переоткрытия файла.
Как отвечать
Для тестировщика это вопрос из практики: стенд упал из-за переполненного диска, автотесты краснеют, и место нужно освободить, не перезапуская сервис. Каркас ответа:
- обнулить файл, а не удалить:
truncate -s 0 app.logили: > app.log. Процесс продолжает писать в тот же дескриптор. Если файл открыт сO_APPEND, запись пойдёт с начала, иначе процесс пишет по старому смещению, и файл становится разреженным; - ротация через
logrotate: режимcreateпереименовывает файл, а вpostrotateпросит процесс переоткрыть лог сигналом или командой, которую приложение поддерживает (у nginx этоUSR1илиnginx -s reopen). Режимcopytruncateнужен, когда приложение переоткрывать файл не умеет, но строки, записанные между копированием и обрезкой, теряются; - сжатие:
compressиdelaycompressвlogrotate, сжимается уже закрытый архив, а не активный файл; - journald:
journalctl --vacuum-size=500Mсразу,SystemMaxUseвjournald.confна будущее; - Docker: драйвер
json-fileс опциямиmax-sizeиmax-file. Они применяются к новым контейнерам, существующий придётся пересоздать; - уровень логирования на лету: если приложение умеет, например Spring Boot через
/actuator/loggers, снизьте DEBUG до INFO без рестарта.
Результат проверяйте через df -h и du -sh, а удалённые, но всё ещё открытые файлы показывает lsof +L1.
Где спотыкаются
Делают rm app.log. Имя пропадает, но процесс держит inode, место не освобождается до перезапуска, а новый файл не появляется.
Запускают gzip на активном логе. Он создаёт архив и удаляет исходник, а процесс продолжает писать в удалённый файл, и диск заполняется ещё быстрее.
Режут уровень логирования до ERROR на стенде, где воспроизводят баги. Места становится больше, но к следующему баг-репорту приложить будет нечего.