Search
Close this search box.

Dynamic log fileNames with log4net

If you needed to generate dynamic logfile names with log4net then you can use the following config

1 : <appender name = "RollingFileAppenderV1" type =
         "log4net.Appender.RollingFileAppender"> 2
    : <file type = "log4net.Util.PatternString" value =
           "F:\HornetFeed\%property{LogName}" /> 3
    : <appendToFile value = "true" /> 4 : <rollingStyle value = "Size" /> 5
    : <maxSizeRollBackups value = "-1" /> 6
    : <maximumFileSize value = "5000KB" /> 7
    : <staticLogFileName value = "true" /> 8 : <countDirection value = "1" /> 9
    : <layout type = "log4net.Layout.PatternLayout"> 10
    : <conversionPattern value = "%m%n" /> 11 : </ layout> 12
    : <filter type = "log4net.Filter.PropertyFilter"> 13
    : <Key value = "Version" /> 14 : <StringToMatch value = "1" /> 15
    : </ filter> 16 : <filter type = "log4net.Filter.DenyAllFilter" /> 17
    : </ appender>

Note the %property{LogName} this is a log4net Property which we can set at runtime using C# code.

 1: log4net.GlobalContext.Properties["LogName"] = "file1.log";

Remember to set the GlobalContext Properties before instantiating the log4net logger. i.e. before this call:

 1: log4net.ILog log = LogManager.GetLogger(typeof(Program));

Also note the “PropertyFilter”

 1: <filter type="log4net.Filter.PropertyFilter">
   2:     <Key value="Version" />
   3:     <StringToMatch value="1" />
   4: </filter>

This Property is also set dynamically at runtime using C# code. We can use ThreadContext to determine which logfile the log entry will be written to. Thus if you wanted that the RollingFileAppenderV1 was used for writing insure that the Thread calling the log.Warn method precedes the call with this following line

 1: log4net.ThreadContext.Properties["Version"] = "1";

If you wanted to use RollingFileAppenderV1 always for logging all messages other than Exception messages then use the following

1 : try
  2 : {
    3 : log4net.GlobalContext.Properties["Version"] = "1";
    4 :  // Business logic with many log.Warn calls
         5:
  }
6 : catch (Exception ex) 7 : {
  8 : LogError(ex);
  9:
}
10 : 11 :  /// Helper method to log errors:
           12 : internal static void LogError(Exception ex) 13 : {
  14 : string state = "1";
  15 : if (log4net.ThreadContext.Properties["Version"] != null) 16
      : state = log4net.ThreadContext.Properties["Version"].ToString();
  17 : log4net.ThreadContext.Properties["Version"] = "0";
  18 : logger.HandleException(ex, "Error");
  19 : log4net.ThreadContext.Properties["Version"] = state;
  20:
}

Note I am using GlobalContext and hence all threads will use this setting to write to log files. No need to set the TrheadContext.Properties on individual threads.

But I prefer to use ThreadContext so that we can control the setting on each thread level.

Also make sure the log4net XML config is set as follows:

1 : <log4net> 2 :       // the following logs only those logs when the Property
                        // Version is set to 1 i.e.
                   3 :  // if Version =1  then log.Warn calls are logged to this
                        // dynamically named file
                        4 : <appender name = "RollingFileAppenderV1" type =
                                 "log4net.Appender.RollingFileAppender"> 5
    : <file type = "log4net.Util.PatternString" value =
           "F:\HornetFeed\%property{LogName}" /> 6
    : <appendToFile value = "true" /> 7 : <rollingStyle value = "Size" /> 8
    : <maxSizeRollBackups value = "-1" /> 9
    : <maximumFileSize value = "5000KB" /> 10
    : <staticLogFileName value = "true" /> 11
    : <countDirection value = "1" /> 12
    : <layout type = "log4net.Layout.PatternLayout"> 13
    : <conversionPattern value = "%m%n" /> 14 : </ layout> 15
    : <filter type = "log4net.Filter.PropertyFilter"> 16
    : <Key value = "Version" /> 17 : <StringToMatch value = "1" /> 18
    : </ filter> 19 : <filter type = "log4net.Filter.DenyAllFilter" /> 20
    : </ appender> 21 : 22
    :  // The following matches and logs all events except Version=1 and
       // Version=2 and strings containing CACHE_CALL_LOG
       23 : 24 : <appender name = "RollingFileAppender" type =
                      "log4net.Appender.RollingFileAppender"> 25
    : <file type = "log4net.Util.PatternString" value =
           "F:\logfiles\trace.log" /> 26 : <appendToFile value = "true" /> 27
    : <rollingStyle value = "Size" /> 28
    : <maxSizeRollBackups value = "10" /> 29
    : <maximumFileSize value = "3000KB" /> 30
    : <staticLogFileName value = "true" /> 31
    : <countDirection value = "1" /> 32
    : <layout type = "log4net.Layout.PatternLayout"> 33
    : <conversionPattern value = "%d [%t] %-5p %c [%x] - %m%n" /> 34
    : </ layout> 35 : <filter type = "log4net.Filter.PropertyFilter"> 36
    : <Key value = "Version" /> 37 : <StringToMatch value = "1" /> 38
    : <acceptOnMatch value = "false" /> 39 : </ filter> 40
    : <filter type = "log4net.Filter.PropertyFilter"> 41
    : <Key value = "Version" /> 42 : <StringToMatch value = "2" /> 43
    : <acceptOnMatch value = "false" /> 44 : </ filter> 45
    : <filter type = "log4net.Filter.StringMatchFilter"> 46
    : <stringToMatch value = "CACHE_CALL_LOG" /> 47
    : <acceptOnMatch value = "false" /> 48 : </ filter> 49 : </ appender>
This article is part of the GWB Archives. Original Author: Rohit Gupta

Related Posts