我有一个服务应用程序,它在启动时读取一个 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/