log4net - BufferingForwardingAppender - 在超时时间内刷新缓冲区

8
我有时会遇到大量日志消息的情况,因此出于性能原因,我不得不使用BufferingForwardingAppender。但是,除了这些突发事件(比如一天发生一次),在其余时间里,我只会收到少量的日志消息。 问题在于缓冲区大小设置为50,这对于突发期间来说是可以接受的,但在没有突发情况的时候,这个缓冲区太大了。在这段时间内,可能需要一个多小时或两个小时才能刷新日志,这在该系统中是无法接受的。
是否有一种方法可以使BufferingForwardingAppender在特定时间间隔(例如每10分钟)内进行刷新,即使缓冲区中没有足够的消息来触发常规进程?
2个回答

8

我可能有些晚了(3年),但在搜索了很多资料后,我找到了能帮助其他人解决这个问题的方法。以下是适用于我情况的解决方案:

<appender name="MyBufferingForwardingAppender" type="log4net.Appender.BufferingForwardingAppender">
      <bufferSize value="1000" /> <!-- flush after 1000 log events -->
      <appender-ref ref="MyRollingFileAppender" />
      <lossy value="false" /> <!-- do not lose any logs -->
      <evaluator type="log4net.Core.TimeEvaluator">
        <interval value="2"/> <!-- flush every two seconds -->
      </evaluator>
</appender>

在 OP 的情况下,他将使用 <interval value="600"/> 每隔10分钟记录一次消息。

1
只要你的回答足够好并且遵循规则,无论何时回答都没问题。 - Nissa
这也存在一个问题,如果在10分钟内没有新事件进来,那么日志将永远不会刷新... - bastos.sergio
@bastos.sergio,它并不会自动刷新。TimeEvaluator会在特定的时间间隔后强制执行刷新。至少在我当时发布这个答案时是这样的。 - André Mantas
昨天我尝试了一下,但是没有成功。缓冲区的日志在时间到期后没有刷新。解决方案的关键是,在10分钟过后必须发生日志以刷新所有内容,如果没有发生,则缓冲区中的所有日志都将保留在缓冲区中...我的解决方法是在应用程序的某些关键点手动强制刷新附加器。 - bastos.sergio
1
我已经查看了“TimeEvaluator”的源代码,似乎它只对新事件做出反应。当新事件到来时,它会检查时间是否过期。因此,在缓冲区中有一些日志项挂起的情况下,只有新事件会刷新附加器,并且如果指定的时间已经过去,则会刷新。 - Eugene D. Gubenkov

1

默认情况下不支持,但是您可以基于BufferingForwardingAppender创建自己的appender:

private static DateTime lastFlushTime = DateTime.Now;
public class TimedBufferingForwardingAppender : BufferingForwardingAppender{
    override protected void Append(LoggingEvent loggingEvent) {
        if (lastFlushTime.AddMinutes(10) < DateTime.Now){
            SendBuffer(new LoggingEvent[] { loggingEvent } );
            lastFlushTime = DateTime.Now;
        }
    }
}

1
我认为唯一的问题是如果没有新事件进来,它就永远不会触发。 - Austin Salgat
是的,你说得对,不过当你有这个例子时,你也能够解决那个问题。 - Peter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接