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>

Print | posted @ Tuesday, March 03, 2009 4:52 PM

Comments on this entry:

Gravatar # re: Dynamic log fileNames with log4net
by Step at 6/22/2009 10:13 AM

Thanks my man. You save my life and my time :)
Gravatar # re: Dynamic log fileNames with log4net
by tine at 7/21/2009 4:23 AM

thanks sir. very well explained. easy to use.
just like Step said, save my life and my time !
hehehhehe
Gravatar # re: Dynamic log fileNames with log4net
by Jack at 9/15/2009 8:28 PM

thanks for sharing! with your tip, we can change the log path or log name during the runtime!
Gravatar # re: Dynamic log fileNames with log4net
by shai at 11/8/2009 9:41 AM

thanks, BUT,
when working with threads,
i get mixed up in the logs
Gravatar # re: Dynamic log fileNames with log4net
by Rajasekar at 11/27/2009 4:13 AM

I am using log4net for my application.. I am able to log the error at application level ie., only one log file for the application.. this is fine.

Mine is web application and several users would be using tht. So I need to log individual user's log to indiviual files.. basically if ten users are accessing the web, I should have 10 log files.

Infact I have found the way for generating files where the file name is dynamic (user id of the user who is accessing).. but I am facing trouble

when user X logged in, a file X.log is created - this is OK
When user Y logged in (after X - log out) , a file Y.log is created - this is OK

Now if there are concurrent access, say X & Y are accessing simultaneously.. I got only one file whose name is - whoever logged in first.. and the log information of second user gets recorded along vit first user. This is where I really need help!
Post A Comment
Title:
Name:
Email:
Website:
Comment:
Verification:
 
Twitter