【问题标题】:How to log to separate log file per thread using log4net如何使用 log4net 记录到每个线程的单独日志文件
【发布时间】:2012-03-26 05:58:29
【问题描述】:

是的,这个问题类似于: How to log into separate files per thread with Log4Net? 除非在运行时之前我不知道线程的数量或它们的名称。我的 Windows 应用程序为每个用户生成一个线程来为该用户执行长时间运行的工作。我希望每个用户/线程都有一个单独的日志文件。

  1. log4net 配置文件是什么样的(如果可以用于这种类型的东西)?
  2. 使用记录器的代码是什么样的?
  3. 我什么时候打电话给log4net.Config.XmlConfigurator.Configure()?

(请详细说明如何实现日志记录。)

这是一个示例配置(我无法让 thread_name 属性与多个线程一起使用):

<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" />
  ...

还有代码:

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
    }
}

如果使用 log4net 不容易做到这一点,我可以将日志框架切换到 Nlog 并使用它们的 %threadname 关键字作为存储在配置文件中的日志文件名的一部分。

【问题讨论】:

  • 是的,这很容易做到。看这里:stackoverflow.com/questions/1324053/…。只需将文件名基于 threadid 或其他一些保证唯一的临时名称。
  • 那行不通。它不断记录到 app.config 中指定的文件。你能给我一个有效的 .net 例子吗?

标签: .net multithreading logging log4net


【解决方案1】:

请试试这个:

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

如果您需要使用 log4net 生成动态日志文件名,那么您 可以使用以下配置

<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

注意 %property{LogName} 这是一个 log4net 属性,我们可以 使用 C# 代码在运行时设置。

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

记得在实例化之前设置 GlobalContext 属性 log4net 记录器。即在此调用之前:

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

然后:

  ///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;
  }

'希望有帮助

【讨论】:

  • 这也不起作用 :) 我知道如何使用 GlobalContext.Properties 动态设置单个日志文件的名称,但我需要为每个线程动态分配不同的日志文件。我不确定过滤器在做什么,但我试过了,它没有做任何事情。
猜你喜欢
  • 2011-10-20
  • 2010-12-09
  • 2020-01-11
  • 1970-01-01
  • 2013-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多