简体   繁体   English

为什么我的log4net appender没有缓冲?

[英]Why isn't my log4net appender buffering?

I've created a custom log4net appender. 我已经创建了一个自定义log4net appender。 It descends from log4net.Appender.SmtpAppender which descends from log4net.Appender.BufferingAppenderSkeleton. 它来自log4net.Appender.SmtpAppender,它来自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. 我希望这会缓冲3个级别错误或更高级别的事件,并在填充缓冲区时传递这些事件。 However, I'm finding that the events are not buffered at all; 但是,我发现事件根本没有缓冲; instead, SendBuffer() is called immediately every time an error is logged. 相反,每次记录错误时立即调用SendBuffer()。

Is there a mistake in my configuration? 我的配置有错误吗?

Thanks 谢谢

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. 当收到级别等于或高于求值程序的消息时,告诉appender刷新缓冲区。 Level.Off will therefore block all events. Level.Off因此将阻止所有事件。

Update: after tracing over the log4net source once more I cannot see why buffering is not working for you. 更新:再次跟踪log4net源后,我看不出为什么缓冲不适合你。

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. Update2:我很难过,但是我再次发现自己忘记了log4net appender需要在更改设置后调用ActivateOptions Until ActivateOptions is called, the internal cyclic buffer is not created and buffering will not happen. 在调用ActivateOptions之前,不会创建内部循环缓冲区,也不会发生缓冲。

So, making a quick test appender: 所以,做一个快速测试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 :). 测试通过(在我的机器上至少:)。

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 to flush the buffer (it would also flush if you reach the buffer size). 我的理解是Threshold告诉log4net何时刷新缓冲区(如果达到缓冲区大小,它也会刷新)。 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 on the 4th error message the messages are sent. 填充缓冲区,并在第4条错误消息上发送消息。 So if you want 3 messages only in the email you have to set the buffer size to 2... 因此,如果您只想在电子邮件中使用3条消息,则必须将缓冲区大小设置为2 ...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM