2010-03-16 59 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