In many cases you want to allow only ERROR logging in production for performance reasons.

I did a little experiment on log4net performance, based on different configurations in the App.config, to try and find out what the best settings are for only allowing ERROR logging in production.

 

First some explanation on the log4net settings used

1. The [Root > Level] is used to only allow logging based on the given value and above for all appenders.

2. The threshold setting is used to allow logging for the given value and above for a specific appender.

3. LevelMatchFiler is used to allow only logging for a specified level for a specific appender.

4. LevelRangeFilter is used to allow only logging between the given values for a specific appender.

 

The App.config with all settings

This App.config shows all settings used, it is not a working App.config.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
  </configSections>
  <log4net>
    <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
      <!-- Allow only ERROR logging for this adapter -->
      <threshold value="ERROR"/>

      <!-- Allow only ERROR logging for this adapter -->
      <filter type="log4net.Filter.LevelMatchFilter">
        <acceptOnMatch value="true" />
        <levelToMatch  value="ERROR" />
      </filter>
      <filter type="log4net.Filter.DenyAllFilter" />

      <!-- Allow only DEBUG, INFO, WARN and ERROR logging for this adapter -->
      <filter type="log4net.Filter.LevelRangeFilter">
        <acceptOnMatch value="true"/>
        <levelMin value="DEBUG"/>
        <levelMax value="ERROR"/>
      </filter>
      
      <file value="Log.txt"/>
      <appendToFile value="true"/>
      <rollingStyle value="Size"/>
      <maxSizeRollBackups value="1"/>
      <maximumFileSize value="100MB"/>
      <staticLogFileName value="true"/>
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date %-5level %type.%method - %message%newline"/>
      </layout>
    </appender>
    <appender name="ADONetAppender" type="log4net.Appender.ADONetAppender">
      <!-- Allow only ERROR logging for this adapter -->
      <threshold value="ERROR"/>
      
      <!-- Allow only ERROR logging for this adapter -->
      <filter type="log4net.Filter.LevelMatchFilter">
        <acceptOnMatch value="true" />
        <levelToMatch  value="ERROR" />
      </filter>
      <filter type="log4net.Filter.DenyAllFilter" />
      
      <!-- Allow only DEBUG, INFO, WARN and ERROR logging for this adapter -->
      <filter type="log4net.Filter.LevelRangeFilter">
        <acceptOnMatch value="true"/>
        <levelMin value="DEBUG"/>
        <levelMax value="ERROR"/>
      </filter>
      
      <bufferSize value="1"/>
      <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
      <commandText value="INSERT INTO Log ([Date],[Thread],[Level],[Logger],[Message]) VALUES (@log_date, @thread, @log_level, @logger, @message)"/>
      <connectionString value="Data Source=myserver.dev.nl\dev2008;Initial Catalog=MyDatabase;Integrated Security=SSPI"/>
      <parameter>
        <parameterName value="@log_date"/>
        <dbType value="DateTime"/>
        <layout type="log4net.Layout.PatternLayout" value="%date{yyyy'-'MM'-'dd HH':'mm':'ss'.'fff}"/>
      </parameter>
      <parameter>
        <parameterName value="@thread"/>
        <dbType value="String"/>
        <size value="255"/>
        <layout type="log4net.Layout.PatternLayout" value="%thread"/>
      </parameter>
      <parameter>
        <parameterName value="@log_level"/>
        <dbType value="String"/>
        <size value="50"/>
        <layout type="log4net.Layout.PatternLayout" value="%level"/>
      </parameter>
      <parameter>
        <parameterName value="@logger"/>
        <dbType value="String"/>
        <size value="255"/>
        <layout type="log4net.Layout.PatternLayout" value="%type.%method"/>
      </parameter>
      <parameter>
        <parameterName value="@message"/>
        <dbType value="String"/>
        <size value="4000"/>
        <layout type="log4net.Layout.PatternLayout" value="%message"/>
      </parameter>
    </appender>
    <root>
      <level value="ERROR" />
      <appender-ref ref="RollingLogFileAppender" />
      <appender-ref ref="ADONetAppender" />
    </root>
  </log4net>
</configuration>

 

 

The code

public void TestLog4NetPerformance()
{
    // Configure Log4Net based on de App.config settings.
    XmlConfigurator.Configure();

    // Create a Log4Net logger object.
    ILog _logger = LogManager.GetLogger("Testing Log4Net on Performance");

    // Capture the start date and time
    DateTime startDateTime = DateTime.Now;

    // Set max for logging callss.
    int max = 100000000;
    for (int i = 0; i < max; i++)
    {
        _logger.Debug("This is a log4net debug log entry.");
    }

    // Capture the end date and time
    DateTime endDateTime = DateTime.Now;

    // Calculate the time spent on logging.
    TimeSpan duration = endDateTime - startDateTime;

    // Output to user
    Console.WriteLine(string.Format("Total duration in seconds: [{0}s]", (int)duration.TotalSeconds));
}

The Results

1. [Root > Level value=”ERROR”] – 100.000.000 – Total duration in seconds: [17s]

2. [threshold value=”ERROR”] – 100.000.000 – Total duration in seconds: [656s]

3. [LevelMatchFilter levelToMatch=”ERROR”] – 100.000.000 – Total duration in seconds: [716s]

4. [LevelRangeFilter levelMin=”ERROR” levelMax = ERROR] – 100.000.000 – Total duration in seconds: [715s]

 

When a setting was used, all other settings where removed from the app.config.

 

So the winner is: Root > Level!!!!!!

2 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.