2010-03-16 68 views
7

我创建了一个自定义的log4net appender。它从log4net.Appender.SmtpAppender下降到log4net.Appender.BufferingAppenderSkeleton。为什么不是我的log4net appender缓冲?

我编程设置在其构造函数的参数如下:

this.Lossy = false; //don't drop any messages 
this.BufferSize = 3; //buffer up to 3 messages 
this.Threshold = log4net.Core.Level.Error; //append messages of Error or higher 
this.Evaluator = new log4net.Core.LevelEvaluator(Level.Off); //don't flush the buffer for any message, regardless of level 

我希望这将缓冲水平误差或更高的3个事件,并提供这些事件时,缓冲区填满。但是,我发现这些事件根本没有缓冲;相反,每次发生错误时都会立即调用SendBuffer()。

我的配置有错误吗?

感谢

回答

8

这条线:

this.Evaluator = new log4net.Core.LevelEvaluator(Level.Off); 

告诉附加器刷新缓冲区时平的消息等于或收到the evaluator以上。因此Level.Off将阻止所有事件。

更新:再次追溯到log4net源后,我看不出为什么缓冲不能为你工作。

Update2:我被难住了,但是我发现自己忘记了log4net appenders在设置被更改后需要调用the ActivateOptions。在调用ActivateOptions之前,不会创建内部循环缓冲区,并且不会发生缓冲。

所以,做一个快速测试的appender:

public sealed class MyBufferingAppender: BufferingAppenderSkeleton 
    { 
     public MyBufferingAppender() 
     { 
      BufferSize = 3; 
      ActivateOptions(); 
     } 

     public readonly List<LoggingEvent> SentEvents = new List<LoggingEvent>(); 
     protected override void SendBuffer(LoggingEvent[] events) 
     { 
      SentEvents.AddRange(events); 
     } 
    } 

...和快速测试:

[Test] 
    public void DoAppend_BuffersEvents() 
    { 
     var appender = new MyBufferingAppender(); 

     appender.DoAppend(new LoggingEvent(
      new LoggingEventData {Level = Level.Error, Message = "Hello world"})); 

     Assert.That(appender.SentEvents, Has.Count(0)); 
    } 

测试通过(我的机器上至少:)。

+1

我的理解是,它告诉appender在收到超过指定阈值的消息时刷新。 http://logging.apache.org/log4net/release/sdk/log4net.Core.LevelEvaluator.html 我也明白Level.Off是最高的门槛。 http://logging.apache.org/log4net/release/sdk/log4net.Core.Level.Off.html 其中之一不正确? – Eric 2010-03-17 13:56:25

+0

@Eric:查看我更新的答案。 – 2010-03-17 21:17:10

+0

很好地完成。这对我有用。谢谢。 – Eric 2010-03-17 22:04:11

3

你想做的事可以用下面的配置做些什么:

<bufferSize value="3" /> 
<lossy value="false" /> 
<filter type="log4net.Filter.LevelRangeFilter"> 
    <levelMin value="ERROR" /> 
    <levelMax value="FATAL" /> 
</filter> 

我的理解是,阈值告诉log4net的时候刷新缓冲区(它会也刷新,如果你到达缓冲区大小)。如果您想从日志中排除邮件,则需要使用过滤器。在代码这工作如下:

this.BufferSize = 3; 
this.Lossy = false; 

var filter = new log4net.Filter.LevelRangeFilter(); 
filter.LevelMin = log4net.Core.Level.Error;   
this.AddFilter(filter); 

Btw。缓冲区被填满并且在第四个错误消息中发送消息。所以,如果你只想在电子邮件3个消息,你必须将缓冲区的大小设置为2 ...

+0

嘿斯特凡。这给了我相同的行为。也就是说,错误消息是立即传递的,而不是缓冲的。 – Eric 2010-03-17 14:29:22

+0

您在代码中删除了“阈值”行吗? – 2010-03-17 17:01:30

+0

我没有删除阈值线。 – Eric 2010-03-17 17:45:24