为什么 Log4Net 过滤器会收到评估器阈值之外的消息?

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

我的 log4net 配置是这样的:

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

如果我在 MyApp.Logging.EmailLogThrottler class 中设置断点,我会看到它正在接收要过滤的 INFO 消息。 EmailLogThrottler 相当昂贵,所以我只希望它根据评估器阈值接收错误消息。这可能吗?

次要问题 - 似乎首先应用过滤器,然后应用评估器阈值(这对我来说是违反直觉的)。这个假设是否正确?

对于你的第一个问题,直接在 appender 上设置阈值 以获得最佳性能:

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

this mailing list post on the difference between threshold and evaluator

threshold 和 evaluator 有什么区别?

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

<threshold value="ERROR" />

Does one discard messages sooner than the other?

答案:

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.

post 继续说关于 Evaluator 的内容,它不是为了过滤消息,而是触发发送缓冲的消息:

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.

过滤器上有这样的话:

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.