Log4j фильтрация для каждого регистратора, основанная на событии

StackOverflow https://stackoverflow.com/questions/1429616

  •  07-07-2019
  •  | 
  •  

Вопрос

Я хотел бы отфильтровать события журнала, поступающие от определенного компонента сторонней библиотеки, на основе содержимого сообщения журнала. Я хочу, чтобы эта фильтрация применялась только тогда, когда событие журнала генерируется определенным регистратором: & 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>
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top