JAVA

индекс
157,29

EDL — Enterprise Dynamic Logger

Долго думал в какой блог можно поместить этот топик: в «Я пиарюсь» или «Java», но остановился на «Java», чтобы получить максимальное количество отзывов и предложений да еще и максимально профессиональных.

Итак, представляю вам Enterprise Dynamic Logger (EDL).

EDL — это тул/фреймворк для несколько другой парадигмы логгинга. В основном нужен для работы в условиях, когда код на сервере менять нельзя и сам сервер перезагружать тоже нельзя. Т.е. production environment.

Общий подход — предварительная автоматическая расстановка log statement’ов в ключевых местах (вход-выход из метода, catch блоки и т.п.) и дальнейшее их динамическое включение runtime с помощью флажков со странички управления EDL.

Кейс использования довольно типичный — где-то на далёком сервере вылетает ошибка. Сходу понять из-за чего — трудно. Но есть предположение, что вот такой метод не вызвался или вызвался не с теми аргументами. Но воспроизвести ошибку локально не получается/долго/трудоёмко. Зато можно было бы посмотреть вызывался ли метод и с какими параметрами прямо на удалённом сервере, но вот незадача — в нужных местах, конечно же, нет логов.

В случае если на сервере установлен EDL (или классы обработаны таской EDL) предлагается следующее:
  • Заходим на страничку EDL управления логированием,
  • включаем логгер,
  • выбираем методы, которые нужно логировать,
  • добавляем по необходимости java expression’ы (чтобы логировать не каждый вызов, а только нужные),
  • жмём кнопку Apply
И логи сразу начинают писаться!

Установка EDL может осуществляться либо подменой Class Loader, либо во время/после компиляции приложения — через bytecode processing.

Плюсы:
  1. Возможность вести анализ, когда код на сервере просто физически недоступен.
  2. Безопасные изменения, нет риска получить эксепшены, т.к. добавляются не произвольные рукописные лог-вызовы, а стандартные по шаблону (использование expressions — это отдельный разговор).
  3. Оптимизированный фреймворк. Во включённом состоянии (без учёта самого процесса записи log сообщений) вносит overhead в пределах всего 1-2% для типичного enterprise use case’а. В выключенном — ещё меньше.
  4. Аспектный подход к логированию — не нужно включать шаблонные лог стейменты («myMethod start», «myMethod end») в сам код в куче мест. Т.е. настройки логгинга можно описать в нескольких отдельных от кода xml файлах (например, по одному на модуль).

Можно использовать как фреймворк для сбора статистики работы путём расстановки expression’ов, которые вызывают свои custom-счётчики и аналогично хранить такие настройки в отдельных файлах. Менять их на production без риска уронить сервер и необходимости перевыдачи приложения с новыми, расставленными вручную, вызовами к счётчикам.

Про эту разработку можно говорить еще очень и очень много, придумывать способы ее применения, но сейчас очень бы хотелось услышать твое мнение, уважаемый %username%, обо всем услышанном. Где бы ты хотел/мог/мечтал использовать что-то подобное? Чего не хватает этой разработке? Какие слабые места ты видишь?
+19
25 ноября 2009, 01:05
13

комментарии (48)

0
remal #
Когда можно будет пользоваться?
+1
ShimON #
Уже очень скоро. Думаю, что месяца через два будет первый релиз кондидат.
+2
zeroed #
Ну и где качать?

Мы на работе сначала хотели такое сделать, потом забили. И тут ВЫ.
0
ShimON #
Качать пока негде, но это не страшно, скоро будет доступно.
+4
consumer #
BTrace?
blog.igorminar.com/2008/06/btrace-dtrace-for-java.html
https://btrace.dev.java.net/
0
ShimON #
Интересно, обязательно изучим. Спасибо!
+2
ShimON #
Да, вещь интересная, но требует достаточного опыта и доступа к шеллу сервера, что не всегда возможно. Также для того, чтобы вставить элементарный лог в начало и конец метода, придется сделать куда больше телодвижений. А вообще — очень приятный и функциональный тул.
0
sse #
Управление через JMX доступно?
0
ShimON #
чем именно вы хотите управлять через JMX?
+1
sse #
Варианты? Логгером, конечно. Или через web-страничку — единственный доступный способ, как указано в тексте?
+1
ShimON #
Способов может быть бесчисленное множество, ведь интерфейс — это всего лишь способ изменения файла настройки.
0
sse #
Спасибо, магистр, я записал твою мудрость.

Вопрос по делу — вы чувствуете разницу между «доступно» и «может быть»? Давайте вы ответите на первый вопрос. А именно — есть ли М-Бины для управления логгером через JMX?
0
ShimON #
Если это так принципиально, то нет. На данный момент их нету.

Ниже можете почитать о том как устроен интерфейс управления EDL на данный момент.
0
akuznetsov #
Вы инструментируйте все классы, если загрузка осуществляется через ClassLoader, в том числе и системные, такие как String, Map? Можно ли каким либо способом указать какие классы необходимо проинструментировать, а какие нет?
+2
ShimON #
Смысл заключается в том, чтобы инструментировать все классы, а потом на этапе отладки уже говорить откуда именно логи необходимы. Подсчитано, что инструментирование всех классов не приведет к ощутимой потере производительности, особенно если логгинг выключен.
0
akuznetsov #
По какой модели будет расспронятся EDL? Open-source с платной подержкой или это будет платный продукт?
+1
ShimON #
Все будет зависеть от интереса сообщества к разработке. Сейчас есть планы на Open-source.
+1
Kinjeiro #
Наконец-то для начала работ достаточно будет лишь одно фразы, обращенной к тестировщиками: «Ваш сервер и testcase, пожалуйста».
Не будет мучительных попыток на дев серверах установить и воссоздать сложную структуру данных реальных рабочих серверов. Иногда для подобного просто физических возможностей не хватает.

Желаю усердия и вдохновения, дабы реализовать эту полезную идея.
0
ShimON #
Спасибо! Будем стараться! Реализовать осталось уже не так много.
0
unchqua #
Всё же возможность включения/выключения журналирования и возможность покатать код по реальным данным — не связанные вещи, нет? Пусть ошибка стала ясна, но commit на пром. сервере уже произошёл, это неприятно.
0
Kinjeiro #
Неприятно =) Но идеального мира нет, и после ошибки приходится разбираться в ее сути. Часто бывает так, что реальные сервера нельзя трогать (даже перезагружать): происходит production тестирование, показ клиенту, реальная работа и т.д. А чтобы разобраться в причине ошибки и пытаться исправить ее необходимо править код, в следствии чего может возникнуть еще больше exceptions.
Поэтому и приходится весь этот шаманизм дублировать на спец серверах, то есть устанавливать инстансы проектного кода, накатывать базу данных, проставлять конфигурации (а это часы и часы), а уж только потом приступать к моделированию и исправлению.

Насколько я понял, с программой, реализованной по концепту EDL, необходимость в доп dev серверах во многих случаях отпадает, что в свою очередь, экономит драгоценные рабочие часы, нервы, время спец. кадров (к примеру, не всегда программист может быть сведущ в бизнес логике клиента, чтобы правильно все настроить).
0
voa #
Не совсем понятно через какой интерфейс производится администрирование. EDL подимает свой web-server или деплоится на tomcat/websphere?
Предусматриваете ли Gui клиент для подключения к EDL как например к JVM через Jconsole?
0
ShimON #
промахнулся с ответом. :( Он комментом ниже.
0
ShimON #
Выше я уже отвечал на подобный вопрос. Вариантов настройки бесчисленное множество и зависит только от наших сил (как разработчиков) и ваших идей (как пользователей). На данный момент есть некоторый протокол общения основанный на HTTP. Реализованного клиента пока нету, но мы, думаю, успеем его сделать к первому кандидату.
–2
cleam #
А в чем преимущество перед log4j. Казалось бы, можно везде поставить debug()'и а потом включать их для отдельных категорий через тот же JMX (по-моему, это стандартная функциональность log4j, а если нет, можно написать)
+1
ShimON #
Например, когда у вас команда разработчиков в 100 человек или из 10, но не сильно обученных или просто нету стандартного механизма логгирования в приложении или если приложение было написано 10 лет назад размером в 1млн строк и т.д. Во всех этих случаях по закону «бутерброда» все падает как раз там, где логов нету.

А так — да, конечно же можно.
0
akuznetsov #
У вас будет перемешан код для бизнеслогики с логированием, это будет сказывается на читабильности. Лучше эти аспекты разделять.
0
ShimON #
Например, когда у вас команда разработчиков в 100 человек или из 10, но не сильно обученных или просто нету стандартного механизма логгирования в приложении или если приложение было написано 10 лет назад размером в 1млн строк и т.д. Во всех этих случаях по закону «бутерброда» все падает как раз там, где логов нету.

А так — да, конечно же можно.
+1
AlexeyTokar #
Общий подход — предварительная автоматическая расстановка log statement’ов в ключевых местах (вход-выход из метода, catch блоки и т.п.) и дальнейшее их динамическое включение runtime с помощью флажков со странички управления EDL.


насколько я понимаю (хотя я и недавно в джаве, так что старожили поправьте), но если проект написан на АОП фреймворке, типа Спринг, то вопросы о подобном вообще не возникают. так?
–5
ShimON #
возникают, т.к.:
1. АОП это статическая модификация, рантайм новый стейтмент не добавишь
2. Перформанс у Aspectj в этом плане весьма так себе (Spring не смотрел), АОП фреймворки не расчитаны на такое кол-во вызовов
+4
sse #
>> АОП это статическая модификация
Неправда ваша. Существуют динамические виверы, как в spring, например.

Непонятно также, чем ваш проект будет обеспечивать большее быстродействие, чем AspectJ, если и в AspectJ, и у вас используется инструментирование байткода?
+2
ShimON #
Коллеги, похоже сейчас получилось некоторое недопонимание по поводу терминов и use case'ов, поэтому стоит сделать следующий необходимый комментарий.

Под динамической модификацией мы понимаем runtime модификацию, без перезагрузки сервера. Насколько я знаю, в АОП фреймворках динамическая модификация — это load-time weaving, т.е. модификация классов в момент их загрузки в соответствии с xml дескриптором, а далее же, чтобы что-то поменять, нужно рестартануть JVM.

По поводу быстродействия вопрос разумный. Дело в том, что если посмотреть на то, как AspectJ добавляет вызовы к advice'ам, то можно увидеть, что он всегда при этом создаёт объект с информацией о текущем joinpoint и укладывает туда аргументы. Это расчитано на типичный кейс использования АОП — если advice добавлен, то он нужен, т.к. он исполняет некоторый код. В случае же с логированием, если логгер вообще выключен, то advice'ы ничего не делают, но объекты оборачивающие аргументы, которые нужно подать в advice, всё равно создаются.

Судя по тому, что в Spring AOP аргументы в общем случае тоже подаются как массив Object[], то очевидно что этот массив нужно создать. Насчёт информации о currentJoinPoint в Spring не знаю, в AspectJ для не-static join points создаётся каждый раз.

Собственно первый прототип был сделан как раз с использованием AspectJ и прилично тормозил даже в выключенном состоянии.

«Такое-то кол-во вызовов» это порядка 1 000 000 вызовов методов за одно открытие странички.

Теперь небольшое summary:

Основной кейс использования — когда нельзя выключить сервер и, например, поменять конфиги АОП. Например production на котором постоянно работают, или нет доступа по ftp в сетку заказчика или какие-то ещё проблемы, нетипичные для маленьких и standalone приложений, но часто встречающиеся в enterprise application'ах. Либо же, когда просто не хочется тратить на это время (например, сервер достаточно долго грузится).

Отсюда и появляются критерии производтельности — в выключенном состоянии логгер не должен подтормаживать систему, во включённом состоянии. Когда включён, но логируется всего, скажем, 1% методов, то проверки тоже не должны тормозить остальные 99% методов. Согласен, с АОП это вполне достижимо, т.к. там мы модифицируем только конкретные методы. Но, опять таки, требует рестарта сервера. А мы модифицируем всё подряд и не требуем рестарта. При этом производительность на том же уровне.
0
AlexeyTokar #
без перезагрузки сервера.

насколько мне известно, то Спринг умеет перечитывать свой сонтекст типа такого:

public void refreshSpringConfiguration(){
        ((ConfigurableApplicationContext)getApplicationContext()).refresh();
}

да — этонужно заложить, так что как минимум одна перезагрузка сервера будет нужна, но затем перечитывать конфиг можно в рантайме
–1
ShimON #
В принципе, можно. Но вспоминаем, что у нас production environment
–3
AlexeyTokar #
и? вы не найдете времени на одну перезугрузку в субботу рано утром? :)
0
ShimON #
Коллега, прочитайте, пожалуйста, коммент, на который отвечаете. Там есть все необходимое, чтобы отпал ваш вопрос.
–2
AlexeyTokar #
да просто нет продакшн серверов, у которых 100% аптайм. такого не бывает
и если «вдруг» вы решаете в инфраструктуру приложения добавить отладчик, то можно найти возможность на перезагрузку сервера (кстати, а может есть что-то типа graceful restart?)

ну да ладно. нет так нет
0
ShimON #
Аптайм меряется не в процентах, а в днях, неделях, месяцах. Возможно это поможет вам понять смысл моих комментов. По поводу «изящного» рестарта ничего не слышал.

Возможно кто-то подскажет?
–2
AlexeyTokar #
конечно в днях и неделях, но если взять момент запуска приложения за 0, а момент, когда приложение уже никому не нужно — 1, то аптайм на протяжении от 0 до 1 будет равен 100%.

про рестарт. такое например есть у апача (так что есть шанс, что томкат может баловать тем же).
0
sse #
Спасибо большое, теперь значительно понятнее, что за мысль вы хотели донести :)
0
akuznetsov #
Очень сильно зависит от реализации. Вот статья на хабре в которой описаны подробные тесты различных подходов.
0
ShimON #
Ссылка очень интересная, но к чему она? Ведь мы не используем рефлексии вообще, да и все фреймворки, затронутые в комментах — тоже.
0
akuznetsov #
Я так понимаю для задачи логивание каждый объект оборачивается в прокси или делается, что то подобное. Это задача сходна с вызовом метода на каком либо объекте с помошью reflection. А в этот статье как разприведены сравнение различных способов вызова метода.
0
ShimON #
Нет, никаких оберток не делается. Инструментируются исходные классы.
+1
AlexeyTokar #
как же не добавишь, если мне достаточно описать новое поведение в xml конфигурации контекста?
создал бин логгера, привязал его к вызову методов определенных классов и вуаля — входы и выходы будут логироваться. или я что-то упустил?

фраза «такое кол-во вызовов» требует уточнения, что бы мы говорили объективно
0
ShimON #
ответил вам в комментарии для sse выше.
0
Sauron #
Звучит весьма и весьма привлекательно.
Несколько удивлён что вы не использовали AspectJ.
Было бы здорово в конечном счёте увидеть этот проект в OpenSource.
Успехов вам.
0
ShimON #
На AspectJ он был написан изначально. Уменьшение перфоманса конечного приложения от 50% до 200%. Нас это не устроило.

Спасибо вам, постараемся оправдать надежды!

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.