c# - 为每个单独的线程记录到单独的日志文件

标签 c# multithreading logging log4net

我有一个服务应用程序,它在启动时读取一个 XML 文件并为 XML 文件中的每个条目启动一个线程。每个线程创建一个工作类的实例,该实例需要一个记录器将任何输出记录到线程特定的日志文件中。

在服务 app.config 中,我将 log4net 配置设置设置为使用 XML appender,文件被指定为 PatternString,如下所示:

<appender name="XmlAppender" type="log4net.Appender.FileAppender">
  <file type="log4net.Util.PatternString" value="D:\Temp\Logs\%property{LogName}.log" />
  <immediateFlush value="true"/>
  <appendToFile value="true" />
  <layout type="log4net.Layout.SimpleLayout" />
</appender>

在创建的每个工作类实例的线程锁定方法中,我使用 log4net.LogManager.GetLogger("MyLogger") 方法获取记录器,然后设置当前线程的 PatternStrings LogName 属性使用 ThreadContext.Properties["LogName"] = "Log name prefix"

所有文件都已创建,但是当调用记录器时,它只是将所有消息记录到一个看似随机的文件中。

我已经搜索了很长时间,试图找到解决方案或对我做错的事情的一些答案,但我没有运气。

有人知道为什么会这样吗?

最佳答案

我想我已经解决了这个问题。步骤如下:

  • 在每个线程上创建一个单独的 ILoggerRepository 对象(在此示例中为 loggerRepository)。
  • 为日志文件名设置 ThreadContexts 属性。
  • 使用 XmlConfiguratior 配置存储库。
  • 使用 LogManager 为该线程使用指定的 LoggerRepository 获取指定的记录器(在 XML 配置文件中)。

作为返回,我得到一个新配置的记录器,指向该线程的相应文件。

XML 配置与最初相同,为了完整起见在此处显示:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>    
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
  </configSections>
  <log4net>
    <logger name="ProductionLogger">
      <appender-ref ref="XmlAppender"/>      
      <level value="ALL"/>
    </logger>
    <appender name="XmlAppender" type="log4net.Appender.FileAppender">
      <file type="log4net.Util.PatternString" value="D:\Temp\Logs\%property{LogName}.log" />
      <immediateFlush value="true"/>
      <appendToFile value="true" />
      <layout type="log4net.Layout.SimpleLayout" />
    </appender>
  </log4net>
</configuration>

创建记录器的代码如下。每次运行此代码时,它都在自己的线程中运行。

ILoggerRepository loggerRepository = LogManager.CreateRepository(logFileName + "Repository");
ThreadContext.Properties["LogName"] = logFileName;
log4net.Config.XmlConfigurator.Configure(loggerRepository);
ILog logger = LogManager.GetLogger(logFileName + "Repository", "ProductionLogger");

到目前为止,这似乎没有任何问题。目前我将继续使用这个解决方案,但如果我发现任何其他问题,我会更新这篇文章。

关于c# - 为每个单独的线程记录到单独的日志文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6956064/

相关文章:

c# - 在 ContinueWith 中观察任务异常

c# - 单击按钮后如何在标签中显示文本

C# 类作为其他类变量,事件范围

c# - ManualResetEventSlim 中单次旋转需要多长时间

android - java.lang.RuntimeException : Can't create handler inside thread that has not called Looper. 准备();

java - log4j2 如何从文件中读取属性变量到 log4j2

Laravel 6 - 如何记录所有访问过的用户的 URL

c# - 无法将事件源重新注册到新的自定义事件日志

当私有(private)实例变量超出范围时,Java 终止线程

python - 如何在Python中正确处理记录器文件大小?