I have run into some strange behavior with log4net and wondered if anyone can explain this to me, I would love to learn more to understand it.
Inside my WPF App.xaml.cs OnStartup override method I have the following code which sets a log4net property used for logging:
// logLocation is a path to a subdir in the users' appdata roaming dir
log4net.GlobalContext.Properties["LogLocation"] = logLocation;
logger = LogManager.GetLogger(typeof(App));
logger.Info("OnStartup: " + string.Join(" ", e.Args));
I do this before I create any other loggers (or so I thought).
In my config file I have the following line:
<file type="log4net.Util.PatternString" value="%property{LogLocation}" />
This works to specify the logging file location. However, I have run into a situation in which this fails - resulting in logging writing to a file name "(null)" in the executing directory.
What seems to cause this is the following pseudo code, which is in the same OnStartup method after the code above:
AnyClass ac = new AnyClass();
ac.NoOp();
where AnyClass has a logger instantiated like this:
private static ILog logger = LogManager.GetLogger(typeof(AnyClass));
The reason I am using pseudo code, is that I can replicate this behavior with any class I instantiate AND call a method on. If no method is called, then the logging path works as expected.
A couple of things to note:
- This works when I run it in the debugger in debug or release mode. The error only appears when I run the exe directly or via 'Start Without Debugging'.
- If the logger is not defined statically - then the problem goes away
If I add a static constructor to AnyClass, then the problem goes away, i.e.:
static AnyClass() {}
If I move the call to ac.NoOp() to a secondary method, which is called by OnStartup - the error goes away.
So, to recap, the error is only caused by instantiating a class with a static logger initialization, and invoking a method on that class within the OnStartup method.
I have several ways to work around this, but I would love to learn more to understand why this is happening.