Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
119 views
in Technique[技术] by (71.8m points)

c# - Logging to an individual log file for each individual thread

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.

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>

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I think I have worked out the issue. The steps follow:

  • 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.

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...