Log4j фильтрация для каждого регистратора, основанная на событии
Вопрос
Я хотел бы отфильтровать события журнала, поступающие от определенного компонента сторонней библиотеки, на основе содержимого сообщения журнала. Я хочу, чтобы эта фильтрация применялась только тогда, когда событие журнала генерируется определенным регистратором: & org.restlet.Component.LogService " ;. Сама фильтрация - это просто базовое совпадение с сообщением о событии в журнале.
У меня есть центральный AsyncAppender, который регистрирует несколько приложений. В случае, если события, поступающие из LogService, не отфильтрованы, я бы хотел, чтобы они обрабатывались так же, как сейчас, то есть отправляются AsyncAppender. Я не хочу добавлять фильтр в AsyncAppender, потому что это кажется ужасно неэффективным (мне не нужно фильтровать ВСЕ события, только те, которые поступают из регистратора LogService).
Итак, я попытался связать LogService logger с пользовательским Appender, который, в свою очередь, связан с пользовательским фильтром:
<appender name="filtered" class="mystuff.FilteredAppender">
<filter class="mystuff.EventFilter"/>
<appender-ref ref="ASYNC"/>
</appender>
<logger name="org.restlet.Component.LogService">
<appender-ref ref="filtered"/>
</logger>
Ошибка, которую я сейчас получаю ...
log4j: ОШИБКА Не задан макет для приложения с именем [отфильтровано].
... говорит мне, что с моим дизайном что-то не так: я не думаю, что мой пользовательский аппендер должен заботиться о макете, так как на самом деле он просто должен передавать или не передавать событие журнала. Кроме того, для этого подхода требуются два пользовательских класса, и один из них (mystuff.FilteredAppender) вообще не добавляет значения - он предназначен только для хранения пользовательского фильтра.
Я бы хотел сделать что-то более чистое, как ...
<logger name="org.restlet.Component.LogService">
<filter class="mystuff.EventFilter"/>
</logger>
... но это, очевидно, не поддерживается каркасом log4j.
Есть ли хороший чистый способ сделать фильтрацию событий так, как я хочу?
Решение
Эта запись на доске объявлений описывает решение, которое я смог получить, работая. Кажется, стыдно использовать AsyncAppender в качестве держателя фильтра, но, похоже, это лучший вариант без создания нового пользовательского Appender. В итоге я получаю:
<appender name="filtered" class="org.apache.log4j.AsyncAppender">
<filter class="mystuff.EventFilter"/>
<appender-ref ref="ASYNC"/>
</appender>
<logger name="org.restlet.Component.LogService" additivity="false">
<appender-ref ref="filtered"/>
</logger>
Но мне, конечно, было бы интересно, если бы кто-нибудь знал о еще лучшем подходе. : -)
Другие советы
Log4J имеет библиотеку дополнений ( JavaDoc) , которая предоставляет LoggerMatchFilter
для фильтрации по именам Logger. Вы задаете имя регистратора и хотите ли принять или отклонить (по умолчанию принимается).
В методе решить
фильтра он сравнивает имя регистратора с LoggingEvent object.getLoggerName ()
на равенство. Это удивительно простой и очевидный фильтр, и я очень удивлен, что он не поставляется по умолчанию с Log4j.
С другой стороны, если вы просто хотите отключить сторонние библиотеки, я считаю полезным следующее:
<!-- LOGGER NEUTER -->
<logger name="org.apache"><level value="WARN"/></logger>
<logger name="org.springframework"><level value="WARN"/></logger>