log4net - BufferingForwardingAppender - flush with timeout
Asked Answered
R

2

8

I have a bursts of log messages at some points, so I had to put BufferingForwardingAppender for performance reasons. But, aside from this bursts (that happen lets say, once a day), during the rest of day, I get a small amount of log messages. Problem is that buffer size is set to 50, which is OK for the burst period, but that's way too much for the periods without burst. In this period, it may take more than an hour or two to flush logs, which is unacceptable in this system.

Is there some way to make BufferingForwardingAppender flush in specific time intervals (eg. every 10 minutes) if not enough messages are in buffer to trigger the usual process?

Raffarty answered 11/10, 2013 at 9:9 Comment(0)
R
9

Guess I'm kinda late to help (3 years), but after searching quite a bit, I found something that might help others reaching this question. This worked for me:

<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>

In OP case, he would use <interval value="600"/> to log messages every 10 minutes.

Residency answered 8/2, 2017 at 19:35 Comment(5)
It doesn't matter when you answer here as long as it's decently good and you follow the rules.Fighterbomber
This also suffers from the problem that if no new events come in after 10 minutes, then the logs will never flush...Comte
@Comte it doesn't. The TimeEvaluator with a specific interval forces the flush after that interval has been elapsed. At least it did for me when I posted this answer back thenFortran
Well, I tried out that yesterday and it didn't work. The logs on buffer didn't flush after the time period had expired. The key to your solution is that a log must happen after the 10 minutes have expired to flush everything, if that does not happen then all logs on buffer will remain on buffer.... My workaround has been to force a flush of the appender manually at certain key points in my app...Comte
I've looked into the sources of "TimeEvaluator" and it seems like it only reacts to the new events. When new event comes, then it does check if the time is expired. So in scenario where you have some log items hanging in the buffer, only a new event will flush the appender AND if specified time passed by.Rudelson
A
1

Not out of the box, but you can make your own appender based on the BufferingForwardingAppender:

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;
        }
    }
}
Altonaltona answered 26/5, 2015 at 8:52 Comment(2)
I think the only issue with this is if no new events come in, this will never trigger.Constantia
Yes you are right, however when you have this example, you will be able to fix that also.Altonaltona

© 2022 - 2024 — McMap. All rights reserved.