apache/logging-log4net

I cannot use TimeEvaluator!

aknaldemir opened this issue · 6 comments

Hi Everyone.

I am using log4net in my .net framework 4.7.2 console project and I want to use BufferingForwardingAppender which is related ADONetAppender. When I use bufferSize and evaluator, it just run as bufferSize. Evaluator is not working.

my code is like that;

<appender name="ADONetAppender" type="log4net.Appender.ADONetAppender">
  <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
  <connectionString value="your-connection-string" />
  <commandText value="INSERT INTO Log ([Date],[Thread],[Level],[Logger],[Message],[Exception]) VALUES (@log_date, @thread, @log_level, @logger, @message, @exception)" />
  <parameter>
    <parameterName value="@log_date" />
    <dbType value="DateTime" />
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date{yyyy-MM-dd HH:mm:ss.fff}" />
    </layout>
  </parameter>
  <!-- Diğer parametreler -->
  <bufferSize value="512" />
</appender>

<!-- BufferingForwardingAppender -->
<appender name="BufferingForwardingAppender" type="log4net.Appender.BufferingForwardingAppender">
  <!-- Buffer size büyük bir değere ayarlanmalı -->
  <bufferSize value="10000" /> <!-- 10000 gibi büyük bir buffer size değeri -->
  <lossy value="true" />
  <fix value="true" />
  
  <!-- TimeEvaluator kullanımı -->
  <evaluator type="log4net.Core.TimeEvaluator">
    <interval value="10" /> <!-- 10 saniyede bir logları yaz -->
  </evaluator>

  <!-- Forwarding appenders -->
  <appender-ref ref="ADONetAppender" />
  <appender-ref ref="ConsoleAppender" />
</appender>

@aknaldemir Can you please post the complete log4net config section?
Did I understand correctly, that you want to buffer the log messages for 10 seconds and write them after this delay to the database?

yes you understood correct. But not just 10 seconds. If buffersize is 23 then I need log again.
My code is like that;

log4net.txt

I can't reproduce the problem you describe (see 5bc3813).

Can you try using a FileAppender instead of AdoNetAppender?

What exactly is your process?
How many events do you log in which time frame?

You need to log at least one more event after the interval (10 s) to trigger a flush of the buffered events.

BTW AdoNetAppender is already a buffering appender. There is no need to insert another buffering appender.

Yes I know AdoNetAppender has a buffering appender. I want like this scenario;
I have a process which has 23 logs in one time.
If 10 seconds are completed, it clears the buffer, and if there are 22 records in the buffer, it clears the buffer again.
However in this case, I can see 22 logs. One log is in the buffer. Buffer ok but evaluator is not working. <appender name="BufferingForwardingAppender" type="log4net.Appender.BufferingForwardingAppender"> <bufferSize value="22" /> <evaluator type="log4net.Core.TimeEvaluator"> <interval value="10" /> </evaluator> <appender-ref ref="ADONetAppender" /> </appender>

This is not how the BufferingAppenders work.
The evaluator is only evaluated when new events are logged, not when "some time passes" (because the logic calling the evaluator is unaware of its internals).
When you really want such a behavior, you can flush with a timer:

  System.Threading.Timer timer = new(Flush, null, 10_000, 10_000);

static void Flush(object? _)
{
  foreach (TAppender appender in LogManager.GetRepository().GetAppenders().OfType<BufferingAppender>())
    appender.Flush();
}

Hope this helps.

Feel free to reopen in case your problem is not solved.