What do both <filter> and <evaluator> in this Logback's <appender>?

603 views Asked by At

In this legacy app I'm working on, here's an excerpt from the logback.xml. Alas I'm not used to this logging framework and I'm having a hard time understanding its configuration, despite reading extensively the filters related page here: https://logback.qos.ch/manual/filters.html

    <appender name="EMAIL_WHATEVER" class="ch.qos.logback.classic.net.SMTPAppender">
        <filter class="com.whatever.logback.MarkerFilter">
            <marker>NOTIFY_WHATEVER</marker>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <evaluator class="ch.qos.logback.classic.boolex.OnMarkerEvaluator">
            <marker>NOTIFY_WHATEVER</marker>
        </evaluator>
        <smtpHost>${smtp}</smtpHost>
        <to>${to}</to>
        <from>${from}</from>
        <subject>Whatever...</subject>
        <append>false</append>
        <layout class="com.whatever.logback.NotificationMailLayout">
            <pattern>%msg</pattern>
        </layout>
    </appender>

I don't understand why there's both a <filter> AND and <evaluator> provided that they seem (to me) to done the same job.

Also the thing is I want to configure another <appender> (a ch.qos.logback.core.FileAppender one) but with almost identical marker-filtering. And I want to understand what I'm doing, not just blindly copy-paste some supposedly-working code/config, with additional personal satisfaction if the solution is neat (understand: simple and concise).

Additional Java code for your information i.e. the MarkerFilter class - the thing here is I don't get why they choose to reimplement it instead of using the ch.qos.logback.classic.turbo.MarkerFilter, as there's a logback-classic-xxx.jar in the build/class path:

public class MarkerFilter extends AbstractMatcherFilter {

    Marker markerToMatch;

    public void start() {
        if (this.markerToMatch != null) {
            super.start();
        } else {
            addError(String.format("The marker property must be set for [%s]", getName()));
        }
    }

    public FilterReply decide(Object event) {
        Marker marker = ((ILoggingEvent) event).getMarker();
        if (!isStarted()) {
            return FilterReply.NEUTRAL;
        }

        if (marker == null) {
            return onMismatch;
        }

        if (markerToMatch.contains(marker)) {
            return onMatch;
        }
        return onMismatch;
    }

    public void setMarker(String markerStr) {
        if (markerStr != null) {
            markerToMatch = MarkerFactory.getMarker(markerStr);
        }
    }

}

...and the Layout which is just an extend:

public class NotificationReferentielMailLayout extends PatternLayout {
    @Override
    public String getContentType() {
        return "text/html";
    }
}
0

There are 0 answers