简体   繁体   中英

How to log to separate log file per thread using log4net

Yes this question is similar to: How to log into separate files per thread with Log4Net? except I don't know the number of threads or their names until runtime. My windows app spawns a thread per user to do long running work for that user. I want a separate log file for every user/thread.

  1. What would the log4net config file look like (if one can be used for this type of thing)?
  2. What would the code look like to use the logger?
  3. When would I call log4net.Config.XmlConfigurator.Configure()?

(Please give details on how to implement the logging.)

Here's a sample config (I can't get the thread_name property to work with multiple threads):

<log4net debug="false">
<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
  <!--need to replace LogDir in code like this:  log4net.GlobalContext.Properties["LogDir"] = "c:\programdata\myapp"-->
  <file type="log4net.Util.PatternString" value="%property{LogDir}\logs\mylogfile_%property{thread_name}.log" />
  ...

And the code:

public class MyMultiThreadedClassForUsers
{
    private log4net.ILog Log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
    public void Start()
    {
        log4net.GlobalContext.Properties("LogDir") = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)        
        log4net.Config.XmlConfigurator.Configure()

        List<IUser> users = GetAllUsersFromDB();

        foreach (IUser user in users) {
            System.Threading.Thread t = new System.Threading.Thread(CallBackMethod);
            t.Name = user.FirstName;
            t.Start();
        }
    }

    private void CallBackMethod()
    {
        // this log message should be sent to a log file named after the current thread System.Threading.Thread.CurrentThread.Name
        // Examples: mylogfile_bob.log, and mylogfile_fred.log, etc...
        Log.Info("Starting work on thread " + System.Threading.Thread.CurrentThread.Name);

        // do long running work here
    }
}

If this is not easily done with log4net I may switch logging frameworks to Nlog and use their %threadname keyword as part of the log file name which is stored in the config file.

Please try this:

http://geekswithblogs.net/rgupta/archive/2009/03/03/dynamic-log-filenames-with-log4net.aspx

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

 <appender name="RollingFileAppenderV1" type="log4net.Appender.RollingFileAppender"> <file type="log4net.Util.PatternString" value="F:\\HornetFeed\\%property{LogName}" /> <appendToFile value="true" /> <rollingStyle value="Size" /> ... <filter type="log4net.Filter.PropertyFilter"> <Key value="Version" /> <StringToMatch value="1" /> ... <= Note the "%property{LogName}" syntax 

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

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

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

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

Then:

  ///Helper method to log errors: internal static void LogError(Exception ex) { string state = "1"; if (log4net.ThreadContext.Properties["Version"] != null) state = log4net.ThreadContext.Properties["Version"].ToString(); log4net.ThreadContext.Properties["Version"] = "0"; logger.HandleException(ex, "Error"); log4net.ThreadContext.Properties["Version"] = state; } 

'Hope that helps

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM