Why do Log4Net Filters Receive Messages Outside of the Evaluator Threshold?

667 Views Asked by At

My log4net config is like this:

    <appender name="SmtpAppender" type="log4net.Appender.SmtpAppender">
      <to value="xxx" />
      <from value="xxx" />
      ...
      <evaluator type="log4net.Core.LevelEvaluator">
        <threshold value="ERROR"/>
      </evaluator>
      <filter type="MyApp.Logging.EmailLogThrottler">
      </filter>
    </appender>

If I set a breakpoint in my MyApp.Logging.EmailLogThrottler class, I see it is receiving INFO messages to filter. The EmailLogThrottler is fairly expensive so I only want it to receive ERROR messages, as per the evaluator threshold. Is this possible?

Secondary question - it seems that filters are applied first and then evaluator thresholds (which is counter intuitive to me). Is this assumption correct?

1

There are 1 best solutions below

0
On BEST ANSWER

For your first question, set the threshold directly on the appender for best performance:

<appender name="SmtpAppender" type="log4net.Appender.SmtpAppender">
  <to value="xxx" />
  <from value="xxx" />
  ...
  <threshold value="ERROR"/>

See this mailing list post on the difference between threshold and evaluator

What is the difference between threshold and evaluator?

<!-- appender ... -->
<evaluator type="log4net.Core.LevelEvaluator">
  <threshold value="ERROR"/>
</evaluator>

<threshold value="ERROR" />

Does one discard messages sooner than the other?

Answer:

The threshold is different to the evaluator.

The threshold is implemented in the AppenderSkeleton and therefore supported by almost all appenders. It is just a simple test that is used to ignore logging events that have a level below the threshold. The threshold is checked early and as a simple test is very performant.

The post goes on to say this about the Evaluator, which is not intended to filter messages, but instead to trigger sending the buffered messages:

The Evaluator is a pluggable object that is used by the BufferingAppenderSkeleton to determine if a logging event should not be buffered, but instead written/sent immediately. If the Evaluator decides that the event is important then the whole contents of the current buffer will be sent along with the event. The evaluator does not function like the threshold or a filter in that it does not discard events.

It has this to say on filters:

Filters have a great deal of flexibility because multiple filters can be chained together to provide fine grained control over the events that are output. Because of this they also have a higher cost in terms of performance, each filter in the chain is an object and is asked to decide on the correct course of action.

In the simple case of the threshold filtering the Threshold property should be used in preference to a filter.