Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Log4Net C# logging issue with multi-thread code execution

I am using Log4Net to log an exception in my .Net Windows service application.

I want to mention that, my windows service application is running with multi-threading execution, which means that each task is being processed on each different thread and I have used Delegate - (BeginInvoke) pattern.

Importantly, I am using dynamic properties to generate multiple log files dynamically with Log4Net based on application's different scenarios.

Now, on every logging/ exception scenarios (in C# method), I have used Logger.Log method to log the info/ exception with Log4Net.

Code (Dynamic file generation)

GlobalContext.Properties[FileNameParameter] = DirectoryName + fileName;
LogManager.Info(logMessage);

Config Settings

<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
      <file type="log4net.Util.PatternString" value="D:\Data\%property{FileName}_info.log"/>
</appender>

The problem is (I believe), due to multi-threaded code execution, I am getting following things with Log4Net which is weird.

  1. Sometime log file generates, but NO message content.
  2. Sometime file itself not generating.
  3. Sometime few file generates, few are NOT generating.

Would you please do let me know why Log4Net behaves like this. I need stable logging with multi-threading code execution.

Thanks in advance!

like image 724
nunu Avatar asked Oct 05 '22 02:10

nunu


1 Answers

I haven't actually tried to do what you are doing, but I can see two problems with your code which would cause problems. (I wouldn't expect logging information to be lost, but I would expect the information to go to the wrong file).

Firstly, you should be using ThreadContext rather than GlobalContext if the property is expected to change on different threads. That issue is trivial to fix.

The second issue may be more problematic. Log4net does not expect the base filename to change during program execution and may continue to write to the old filename even after you have changed your property.

One of the easiest ways around this is to re-initialize your logger. If you are using xml configuration from your app.config, you can call log4net.Config.XmlConfigurator.Configure(); after you have set your property. This obviously has an overhead and you have to decide whether this overhead is acceptable.

like image 65
sgmoore Avatar answered Oct 13 '22 10:10

sgmoore