Search code examples
c#.netlog4net

Why would my application hang if my config file is missing a log4net configuration section?


I have an application (a console application that is self-hosting the ASP.Net WebAPI) that is calling XmlConfigurator.Configure() as part of its setup.

It works fine if my application's app.config file looks like this:

<configuration>
    <configSections>
        <section name="log4net"
                 type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
    </configSections>

    <log4net>
    </log4net>
</configuration>

It hangs if I take out the empty <log4net> element:

<configuration>
    <configSections>
        <section name="log4net"
                 type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
    </configSections>
</configuration>

I haven't seen this behaviour anywhere else when using log4net in the past (it usually just puts the message "log4net:ERROR XmlConfigurator: Failed to find configuration section 'log4net' in the application's .config file." out to the console).

Am I doing anything wrong, or have I stumbled across a bug in log4net?


I have debugged this extensively. There are two behaviours:

  1. the call to XmlConfigurator.Configure() hangs indefinitely when I step over it
  2. the call to XmlConfigurator.Configure() can be stepped over, but then the application seems to hang. If I pause execution and look at the active threads, there is one stuck in a log4net method (something like ConfigureFromFile).

Either way, it hangs the whole application.

Here is the stacktrace from the hung thread (in the second case above):

stack trace


Solution

  • I got to the bottom of this in the end thanks to this blog post.

    It basically boils down to the fact that I have .Net 4.5 installed on my machine. Even though I am targeting .Net 4.0, the behaviour is different due to the nature of the drop-in-replacement nature of .Net 4.5.

    Without the empty <log4net> element in my configuration file, log4net wants to write to standard error to notify that the element is empty. Without the element, no logging occurs. When the logging does occur (which happens on a different thread to other Console use in the application), it hits a deadlock caused by a change in how the Console is initialised in .Net 4.5 (detailed in the linked blog post).