16

I finally tried log4net for my WPF desktop application.

I'm struggling with the fact that RollingFileAppender has no built in support for multiple instance application.

I don't like an idea of restricting the application to single instance just to make logger happy. Single intstance tricks are all ugly hacks.

Using process ID in the filename of the log file is also not good enough. This has potential of eating up unlimited space, since RollingFileAppender is useless in this situation.

One solution would probably be to send logs to different process, which would take care of serializing the output into files. But this creates new headaches.

What's your take on this?

Enrico Campidoglio
  • 47,702
  • 11
  • 112
  • 146
Kugel
  • 17,248
  • 12
  • 64
  • 100
  • 1
    Can you send the logs to a web service and store it centrally? This way you can respond quickly to problems users have. – Steven Apr 20 '11 at 09:42
  • 1
    @Steven: that adds a requirement of network connectivity. Not always interesting. – R. Martinho Fernandes Apr 20 '11 at 09:53
  • @Martinho: You can build the mechanism in such way that info is logged locally when network is not available and resent when the network becomes available again. Of course you need to write it yourself. – Steven Apr 20 '11 at 09:58

3 Answers3

18

It's not a good idea to use multiple RollingFileAppender instances from different processes writing to the same file since the RollingFileAppender isn't designed for that scenario.

You have a couple of choices here:

Multiple FileAppender with minimal locking

Use multiple FileAppender instances pointing at the same file and configured with minimal locking. This will allow concurrent write operations from multiple processes:

<appender name="FileAppender" type="log4net.Appender.FileAppender">
    <file value="Log.txt" />
    <appendToFile value="true" />
    <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
    <layout type="log4net.Layout.PatternLayout">
        <conversionPattern
            value="%date [%thread] %-5level %logger - %message%newline" />
    </layout>
</appender>

Multiple EventLogAppender

Use multiple EventLogAppender instances that write to a shared Windows event source:

<appender name="EventLogAppender" type="log4net.Appender.EventLogAppender" >
    <applicationName value="MyApp" />
    <layout type="log4net.Layout.PatternLayout">
        <conversionPattern
            value="%date [%thread] %-5level %logger - %message%newline" />
    </layout>
</appender>

Of course you could also send the log to a database or to a remote component running in a different process or even a different machine but these choices require more infrastructure to be setup so it may be overkill for your scenario.

Related resources:

Enrico Campidoglio
  • 47,702
  • 11
  • 112
  • 146
  • Thank you for pointing out FileAppender. I thought it was superceeded by Rolling cousin. – Kugel Apr 23 '11 at 15:12
2

Another option when you want to log to the rolling files and avoid risks of writing to the same log file is to programmatically change the name of the log4net log file path. For example, you could pass the log file name or some part of it as process start-up parameter and then set it from the code.

Just make sure you do that path change before any logging occurs. Otherwise, similar configuration to the 'Multiple FileAppender with minimal locking' from the previous answer can be used.

Community
  • 1
  • 1
0

Easiest option to solve it by adding any environment variable in the path of log file. For example: In my case, we need application instance per windows user profile. So we include "USERNAME" environment variable in log file path of "RollingFileAppender" as below:

 <file value="Logs/${USERNAME}/Log.txt"/>
Sumit Gupta
  • 755
  • 7
  • 9