Why isn't my log4net appender buffering?
c#, log4net, logging
Solution
This line:
this.Evaluator = new log4net.Core.LevelEvaluator(Level.Off);
tells the appender to flush the buffer when a message with level equal or above the evaluator is received. `Level.Off` will therefore block all events.
Update: after tracing over the log4net source once more I cannot see why buffering is not working for you.
Update2: I was stumped, but again, I found myself forgetting about log4net appenders need for the ActivateOptions to be called after settings have been changed. Until `ActivateOptions` is called, the internal cyclic buffer is not created and buffering will not happen.
So, making a quick test 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);
}
}
...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 :).
Problem
I've created a custom log4net appender. It descends from log4net.Appender.SmtpAppender which descends from log4net.Appender.BufferingAppenderSkeleton. I programatically setup the following parameters in its 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 would buffer 3 events of level Error or higher and deliver those events when the buffer is filled. However, I'm finding that the events are not buffered at all; instead, SendBuffer() is called immediately every time an error is logged. Is there a mistake in my configuration? Thanks