2011-04-09 2 views
10

Я работаю с кодовой базой компании, у которой есть политика написания большого количества протоколов трассировки. Так почти каждый метод имеет кусок кода, который начинается так:Использование аннотаций для ведения журнала трассировки

String LOG_METHOD = "nameOfMethod(String,List<Long>):void"; 
if(logger.isTraceEnabled()) { 
    Object[] params = new Object[] { string, list }; 
    logger.trace(CompanyMessages.newMethodInstanceMessage(this, LOG_METHOD, params)); 
} 

и конец, как это (либо в finally -clause или просто в конце метода:

if(logger.isTraceEnabled()) { 
    logger.trace(CompanyMessages.leaveMethodInstanceMessage(this, LOG_METHOD)); 
} 

Там на самом деле это больше кода, но это основная идея. Это загромождение кода, и другие кодеры постоянно испортили его своими интерпретациями, которые не используют конкретный класс CompanyMessages, который необходим для форматирования сообщений до читайте инструменты мониторинга. Поэтому я ищу способ избавиться от все код выше и просто предоставить все методы, которые требуют отслеживания с аннотациями, такими как: @LogBefore('logLevel') & @LogAfter('logLevel').

Причина, по которой я выбираю это решение, - это сделать так, чтобы другим разработчикам не приходилось изучать что-либо новое, кроме как использовать аннотации вместо кода. Я работаю в среде сервера, в которой мы развертываем сотни веб-приложений и десятки разработчиков. Поэтому я искал способ реализовать это в веб-приложении без большого количества дополнительного кодирования или дополнительных больших библиотек. Это означает, что я ищу небольшую стабильную реализацию АОП, используя аннотации, подобные тем, которые я предложил, легко настраиваемые в каждом веб-приложении. Производительность также важна. Каков самый простой пример для реализации этого с помощью АОП?

Редактировать: Я нашел something very similar, что я ищу, но у этого есть пара проблем. Все классы, требующие ведения журнала, должны быть настроены, что будет более ресурсоемким, чем просто использование аннотаций. Будет ли конфигурация пружины <aop:aspectj-autoproxy/> исправить это?

ответ

3

Я не думаю, что аннотации были решением. Чтобы аннотировать класс или экземпляр означает предоставление дополнительных сведений о классе во время выполнения, он сам по себе ничего не делает. Вам понадобится код, который обрабатывает классы с аннотациями и добавляет код до и после каждого метода на основе этих аннотаций во время выполнения.

Таким образом, при добавлении аннотаций и готовности к работе вы не начинаете вводить их методы.

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

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

+0

Спасибо, это заставило меня понять, что мой взгляд на работу аннотаций был испорчен. – mahler

5

Похоже Аспект-ориентированное программирование (АОП) может реально помочь вам с этим. Это отлично подходит для решения этих сквозных задач, таких как ведение журнала и отслеживание, и поддерживает аннотации, подобные тем, которые вам нужны.

Посмотрите на AspectJ или Spring AOP.

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

4

Аннотации и пункты АОП действительны. Используйте аннотации, чтобы предупредить структуру AOP о регистрации.

Еще одна вещь, которую я бы сделал - это исправить ваш регистратор.

У вас есть:

String LOG_METHOD = "nameOfMethod(String,List<Long>):void" 
if(logger.isTraceEnabled()) { 
    Object[] params = new Object[] { string, list }; 
    logger.trace(CompanyMessages.newMethodInstanceMessage(this, LOG_METHOD, params)); 
} 

Вместо рассмотреть что-то вроде этого:

logger.trace(this, LOG_METHOD, string, list); 

и вы можете реализовать это следующим образом:

public void trace(Object obj, Object args...) { 
    if (parentLogger.isTraceEnabled()) { 
     logger.trace(CompanyMessages.newMethodInstanceMessage(obj, LOG_METHOD, args); 
    } 
} 

Большинство лесозаготовительных утилиты были написаны прежде чем мы имели varargs в Java, таким образом мы все еще видим вещи как то, что Вы написали.

Мы все еще хотим, чтобы охрана для предотвращения вызова журнала, когда он не включен, но основная мотивация для этого, потому что большинство людей в прошлом, будут делать то, что вы сделали, или, что еще хуже:

logger.trace("My message: " + string + " with list " + list); 

У кого есть дорогое выражение, включен ли трассировка или нет.

Но, используя варгары, вы можете получить оба. Просто используйте что-то вроде MessageFormat (который вы, вероятно, делают уже), вы можете легко получить:

logger.trace("My message: {0} with list {1}", string, list); 

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

Большинство современных логгеров не переопределяют красиво, поэтому вам обычно приходится инкапсулировать его, а не просто расширять.

Это не позволяет решить вашу проблему напрямую, динамически генерируя информацию о трассировке. Но это простая промежуточная площадка, которая легко и постепенно очищает существующую базу кода.

Кроме того, есть еще 2 варианта.

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

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

Существует проект, имя которого ускользает от меня, что использует это. Он автоматически добавляет сеттеры/геттер к вашему коду при компиляции. Я слышал об этом.

Основы AOP вполне могут сделать это для вас при компиляции, я не достаточно знаком с ними, но в любом случае технику стоит изучить.

Как минимум, оберните ваш регистратор. Он поэтапный, безопасный и постепенно очистит ваш код и поможет вам вести журнал, где аннотации могут не работать для вас в целом.

Смежные вопросы