1

I wanted to write logs in two different files using log4net, one in the global log file while the other for particular user file, for this I set the param in appender like this

<param name="File" value="D:\Projects\Web\Web\Services\Log\%property{LogFileName}" />

And defined a function like this

public void AddInfo(string message)
{
    log4net.GlobalContext.Properties["LogFileName"] = this.UserId + ".txt";
    log4net.Config.XmlConfigurator.Configure();
    Logger.Info(message);

    log4net.GlobalContext.Properties["LogFileName"] = "ServiceLog.txt";
    log4net.Config.XmlConfigurator.Configure();
    Logger.Info(message);        
}

This all is working find, every log is written in two different files successfully.

My concern is, is the approach correct if we think about performance?

For each and every log it will configure log4net two times, will it affect performance negatively?

Sergey Berezovskiy
  • 232,247
  • 41
  • 429
  • 459
Pawan Nogariya
  • 8,330
  • 12
  • 52
  • 105

1 Answers1

1

Create two file appenders - one for user log (with pattern for file name), and another for global log:

<appender name="UserFileAppender" type="log4net.Appender.RollingFileAppender">
  <file type="log4net.Util.PatternString" value="%property{userId}.txt" />
  ...
</appender>
<appender name="GlobalFileAppender" type="log4net.Appender.RollingFileAppender">
  <file value="log.txt" />
  ...
</appender>
<root>
  <level value="DEBUG" />
  <appender-ref ref="UserFileAppender" />
  <appender-ref ref="GlobalFileAppender" />
</root>

Then configure log4net only once per user:

GlobalContext.Properties["userId"] = "Bob";
XmlConfigurator.Configure();

And use loggers in your application.

Sergey Berezovskiy
  • 232,247
  • 41
  • 429
  • 459
  • Thanks Man! a good solution, but I want to write log to both the files so if I configure it for user then it will not write log to the global file, no? Or am I missing something? – Pawan Nogariya Jun 03 '13 at 09:24
  • 1
    Nope, log4net will write log event to all appenders which are configured for current logger and match level of event. So, in this case event will be passed to both appenders. Btw there shold be some way to avoid configuration for each user. Hold on, I'll update an answer. – Sergey Berezovskiy Jun 03 '13 at 09:32
  • @PawanNogariya take a look on [RollingPatternFileAppender](http://mysite.verizon.net/vze14bhji/) I think you can use it for user log files. Also consider to write user logs into database. – Sergey Berezovskiy Jun 03 '13 at 09:44
  • Is there a way to disable user level appender if we don't get valid userid? – Pawan Nogariya Jun 03 '13 at 10:03
  • 1
    @PawanNogariya you can set appender's threshold at runtime. E.g. `var appender = LogManager.GetRepository().GetAppenders().OfType().SingleOrDefault(a => a.Name == "UserFileAppender")); appender.Threshold = Level.Off;` – Sergey Berezovskiy Jun 03 '13 at 10:37
  • Yes, I found that and tried and it worked but it still created the file with this name `%property{userid}.log`. It would stop logging after setting the level off but what I am trying is to not let it create file at all if userid is not valid. – Pawan Nogariya Jun 03 '13 at 10:42
  • @PawanNogariya take a look on [how to disable creation of empty log file on app start](http://stackoverflow.com/questions/2533403/log4net-how-to-disable-creation-of-empty-log-file-on-app-start). Sorry, I need to go now – Sergey Berezovskiy Jun 03 '13 at 10:49
  • 1
    This is exactly what I wanted!! You helped me a lot!! Thanks!! :) – Pawan Nogariya Jun 03 '13 at 10:52
  • Its working now, but it inserts entries from different users to different files when multiple requests goes at the same time to service. I have Logger defined globally and static, I tried removing static, but didn't work. Any idea? – Pawan Nogariya Jun 03 '13 at 13:11