Обработка и ротация файлов журналов Nginx

Читайте журналы построчно в бинарном режиме, фильтруйте строки и ротируйте результат до записи строки, которая превысит лимит 200 МБ.

Короткий ответ

Что ответить на собеседовании

Читайте журналы построчно в бинарном режиме, фильтруйте строки и ротируйте результат до записи строки, которая превысит лимит 200 МБ.

Подробный разбор

Ответ с пояснениями

Условие

Веб‑сервер Nginx сохраняет запросы в файл /var/log/nginx/access.log. Каждый день происходит ротация, поэтому в каталоге /var/log/nginx появляются несколько файлов:

  • /var/log/nginx/access.log – текущий журнал;
  • /var/log/nginx/access.log.1 – журнал за предыдущий день;
  • /var/log/nginx/access.log.2 – журнал за два дня назад;
  • /var/log/nginx/access.log.3 и т.д.

Ротация запускается в полночь, но размеры файлов могут сильно различаться – в зависимости от нагрузки за день. Требуется написать утилиту, которая будет сканировать все файлы журнала (access.log и *access.log.**) в указанной директории, искать в них строки, соответствующие заданному шаблону (например, при шаблоне «favicon.ico» следует вывести все строки, где встречается «favicon.ico»).

Найденные строки необходимо сохранять в файл /var/log/nginx/parsed/lines.txt. Размер этого файла не должен превышать 200 МБ. Как только размер достигает лимита, файл должен быть переименован в /var/log/nginx/parsed/lines.txt.1 (при последующих ротациях – в .2, .3 и т.д.), а затем создать новый пустой /var/log/nginx/parsed/lines.txt и продолжить запись.

Таким образом, при каждом достижении 200 МБ происходит очередная ротация результата, формируя последовательную нумерацию файлов в каталоге parsed.

Ответ

Читайте журналы построчно в бинарном режиме, фильтруйте строки и ротируйте результат до записи строки, которая превысит лимит 200 МБ.

Зафиксируйте список входных файлов перед обработкой, исключив каталог parsed. При необходимости обрабатывайте .gz через gzip. Размер измеряйте в байтах: для десятичных 200 МБ лимит равен 200_000_000.

Алгоритм записи совпавшей строки:

  1. Если сама строка больше лимита, сообщить об ошибке: сохранить её целиком с таким ограничением невозможно.
  2. Если текущий_размер + размер_строки > лимит, закрыть lines.txt, переименовать в следующий свободный lines.txt.N и открыть новый.
  3. Записать строку и обновить счётчик; при точном достижении лимита также выполнить ротацию.

Не перезаписывайте существующие архивы. Для однократного запуска достаточно последовательного чтения; для постоянного наблюдения нужны inode/offset и защита от повторной обработки при ротации Nginx. Обработку гигантских строк следует ограничить по памяти.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее