为每个单独的线程记录到单独的日志文件 [英] Logging to an individual log file for each individual thread
问题描述
我有一个服务应用程序,它在启动时读取一个 XML 文件并为 XML 文件中的每个条目启动一个线程.每个线程创建一个工作类的实例,它需要一个记录器将任何输出记录到线程特定的日志文件中.
I have a service application that on startup reads an XML file and starts a thread for each entry in the XML file. Each thread creates an instance of a worker class which requires a logger to log any output to a thread specific log file.
在服务 app.config 中,我将 log4net 配置设置设置为使用 XML 附加程序,并将文件指定为 PatternString,如下所示:
In the services app.config I have the log4net configuration settings set to use an XML appender and the file is specified as a PatternString as shown below:
<appender name="XmlAppender" type="log4net.Appender.FileAppender">
<file type="log4net.Util.PatternString" value="D:TempLogs\%property{LogName}.log" />
<immediateFlush value="true"/>
<appendToFile value="true" />
<layout type="log4net.Layout.SimpleLayout" />
</appender>
在创建的每个工作类实例的线程锁定方法中,我使用 log4net.LogManager.GetLogger("MyLogger")
方法获取记录器,然后设置当前线程 PatternStrings LogName 属性使用 ThreadContext.Properties["LogName"] = "日志名称前缀"
.
In a thread locked method for each instance of the worker class created I get the logger using the log4net.LogManager.GetLogger("MyLogger")
method and then I set the current threads PatternStrings LogName property using ThreadContext.Properties["LogName"] = "Log name prefix"
.
所有文件都已创建,但当记录器被调用时,它只会将所有消息记录到一个看似随机的文件中.
All of the files are created but when the logger is called it just logs all message to one seemingly random file.
我已经搜索了很长时间,试图为我做错的事情找到解决方案或答案,但我没有运气.
I have searched about for quite a while trying to find a solution or some answers to what I am doing wrong but I have had no luck.
有人知道为什么会这样吗?
Does anyone have any idea why this is happening?
推荐答案
我想我已经解决了这个问题.步骤如下:
I think I have worked out the issue. The steps follow:
- 在每个线程上创建一个单独的
ILoggerRepository
对象(在本例中为loggerRepository
). - 为日志文件名设置 ThreadContexts 属性.
- 使用 XmlConfiguratior 配置存储库.
- 使用 LogManager 使用该线程的命名 LoggerRepository 获取命名记录器(在 XML 配置文件中).
- Create an an individual
ILoggerRepository
object (loggerRepository
in this example) on each thread. - Set the ThreadContexts property for the log file name.
- Use the XmlConfiguratior to configure the repository.
- Use the LogManager to Get the named logger (in the XML configuration file) using the named LoggerRepository for that thread.
作为回报,我得到一个新配置的记录器,指向该线程的相应文件.
In return I get a new configured logger pointing to the respective file for that thread.
XML 配置与原始配置相同,为了完整起见,此处显示:
The XML configuration is the same as it was originally and shown here for completeness:
<?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:TempLogs\%property{LogName}.log" />
<immediateFlush value="true"/>
<appendToFile value="true" />
<layout type="log4net.Layout.SimpleLayout" />
</appender>
</log4net>
</configuration>
创建记录器的代码如下.每次运行此代码时,它都会在自己的线程中运行.
The code to create the loggers is below. Each time this code is run it is run in its own thread.
ILoggerRepository loggerRepository = LogManager.CreateRepository(logFileName + "Repository");
ThreadContext.Properties["LogName"] = logFileName;
log4net.Config.XmlConfigurator.Configure(loggerRepository);
ILog logger = LogManager.GetLogger(logFileName + "Repository", "ProductionLogger");
到目前为止,这似乎没有问题.目前我将继续使用此解决方案,但如果我发现其他任何问题,我会更新这篇文章.
This seems to work with no issues so far. I will be moving forward with this solution for the moment but I will update this post if I find out anything else.
这篇关于为每个单独的线程记录到单独的日志文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!