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