воскресенье, 23 июня 2013 г.

Log4j, Blitz4j и все-все-все

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

Logstash - нам не подощел из-за особенностей нашей сетевой инфраструктуры, поэтому делаем собственное решение.

Одной из частей этой системы является сервис записи логов в файловое хранилище на локальный диск. Данное требование появилось в связи с необходимостью быстро писать большие объемы логов (INFO, DEBUG) для последующего разбора. По сети DEBUG логи передавать очень тяжело - объемы слишком большие.

Вот о сервисе локальной записи и варианте его реализации с помощью Blitz4j я и расскажу. Возможно вы уже слышали / читали о Blitz4j. Это "Logging framework for fast asynchronous logging" от команды Netflix, подробнее можно узнать в их статье Announcing Blitz4j - a scalable logging framework. К сожалению на этом информация о библиотеке заканчивается.

Но я поверил слухам и решил проверить его в деле. Изначально у меня была реализация локального логирования с помощью Log4j и RollingFileAppender. Решение в принципе стабильное, но нагрузка растет и мы решили опробовать хваленый Blit4j.

Если внимательно читать статью в инженерном блоге Netflix, то становится понятно что Blitz4j это не самостоятельный framework для логирования. Это расширение Log4j, которое заменяет и дополняет часть его внутренней реализации собственными версиями классов. В основном внимание было уделено многопоточной работе и устранению блокировок внутри Log4j. Для этого в том числе активно использовали новые наработки из java.util.concurrent и guava.

Т.е. мы
  • пишем обычный логгер с использованием Log4j
  • добавляет в classpath blitz4j и еще немного зависимостей (например servo)
  • изменяем конфигурацию Log4j
и надеемся на профит.

Blitz4j предоставляет возможность обернуть существующие Log4j appenders в специальный асинхронный wrapper. Важные возможности, которые он дает:
  • внутренний промежуточный буфер сообщений, в который сохраняются поступающие сообщения
  • встроенная возможность группировки сообщений при наступлении проблемных ситуаций, когда не успеваем писать поступающие сообщения на диск
    • к сожалению результат группировки сообщение отражает только сам факт группировки. Восстановить потерянные данные невозможно.
  • набор ручек и кнопочек для тюнинга
На своем тестовом стенде переход на Blitz4j позволило мне получить прирост в 30% сообщений, записываемых в секунду (при 20-100 потоках генерации сообщений). При этом при постепенном росте количества потоков с 20 до 100 Blitz4j обеспечивает более ровный response time.

Итог

Вам стоит посмотреть на Blitz4j, если вы:
  • пишете логи локально
  • с помощью Log4j
  • из 10 и более потоков одновременно
  • используя стандартные FileAppender / RollingFileAppender
Нам пришлось от данного решения отказаться - blitz4j работает со статической конфигурацией. А мы в свою очередь активно создаем и конфигурируем новые logger и appender в runtime (для каждого компонента системы). Скрестить это с blitz4j пока не получилось. Но если мы упремся в скорость записи логов - мы вернемся к этому решению.