Filtering log4j for each logger based on event

I would like to filter log events originating from a specific 3rd party library component based on the content of the log message. I want this filtering to be applied when a log event is generated by a specific logger: "org.restlet.Component.LogService". The filtering itself is just a basic match with the log event message.

I have a central AsyncAppender that registers across multiple applications. In case the events coming from the LogService are not filtered, I would like to be handled with the same as now, that is, send them to AsyncAppender. I don't want to add a filter to the AsyncAppender because it seems terribly inefficient (I don't need to filter ALL events, only those that come from the LogService).

So what I was trying to do was link the LogService to a custom Appender, which in turn is linked to a custom filter:

    <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>

      

The error I am currently getting ...

log4j: ERROR Missing layout for application named [filtered].

... tells me something is wrong with my design: I don't think my custom appender should care about the layout, as it really just needs to pass or not pass the log event. Also, this approach requires two custom classes, and one of them (mystuff.FilteredAppender) doesn't add any value at all - it only has to contain the custom filter there.

I would like to do something much cleaner like ...

    <logger name="org.restlet.Component.LogService">
            <filter class="mystuff.EventFilter"/>
    </logger>

      

... but this is obviously not supported by the log4j framework.

Is there a good clean way to do event filtering the way I want to do it?

+2


source to share


2 answers


This post describes the solution that I was able to get. It seems a shame to use AsyncAppender as a filter holder, but it looks like it's the best option without creating a new custom Appender. So I get:

    <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>

      



But I would be wondering if anyone knows of an even more suitable approach. :-)

0


source


Log4J has Extras Library (JavaDoc) which provides LoggerMatchFilter

Logger name filtering. You give the registrar name and accept or reject (accept by default).

In the decide

filter method, it compares the log name with LoggingEvent object.getLoggerName()

for equality. This is an amazingly simple and obvious filter, and I'm very surprised that it doesn't come by default with Log4j.



Alternatively, if you just want quiet third party libraries, I found the following helpful:

<!-- LOGGER NEUTER -->
<logger name="org.apache"><level value="WARN"/></logger>
<logger name="org.springframework"><level value="WARN"/></logger>

      

0


source







All Articles