Why not buffering app log4net appender?

I created a custom log file. It exits log4net.Appender.SmtpAppender, which descends from log4net.Appender.BufferingAppenderSkeleton.

I programmatically configure the following parameters in my constructor:

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 

I expect this to buffer 3 events of Error level or higher and deliver these events when the buffer is full. However, I found that the events are not buffered at all; instead, SendBuffer () is called immediately every time an error is logged.

Is there an error in my configuration?

thanks

+7
c # logging log4net
source share
2 answers

This line:

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

tells the application to flush the buffer when a message is received with a level equal to or higher by the evaluator . Level.Off will block all events.

Update: after tracing by log4net source again. I do not understand why buffering does not work for you.

Update2: I was at a dead end, but again I forgot that for log4net appenders applications ActivateOptions is required to be called after changing the settings. Until ActivateOptions is called, an internal circular buffer is not created and buffering will not be performed.

So, making a quick test application:

  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); } } 

... and a quick test:

  [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)); } 

The test passes (on my machine at least :).

+8
source share

What you want to do can be done with the following configuration:

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

My understanding is that Threshold tells log4net when it needs to flush the buffer (it will also be hidden if you reach the buffer size). If you want to exclude messages from the log, you need to use a filter. In code, this works as follows:

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

Btw. the buffer is filled, and messages are sent on the fourth error message. Therefore, if you need only 3 messages only in the letter, you need to set the buffer size to 2 ...

+3
source share

All Articles