Search code examples
asp.net-mvcasp.net-web-apiunity-containerlog4net

Log4Net not logging in .NET WebApi project using UnityContainer


I have a very basic C# .NET WebApi project using Unity.AspNet.WebApi and Unity.Mvc for dependency injection and Unity.log4net for logging.

The injection into my controllers seems to be working correctly. The problem is that the logger never logs anything. The expected .log file is never created. When I inspect the logger object while debugging it has all the levels disabled (IsDebugEnable = false, IsErrorEnabled = false, etc.)

It is running as if has ignored my log4net.config file. In the root of my project I have a log4net.config file that defines a console and a file appender.

<log4net>
  <root>
    <level value="ALL" />
    <appender-ref ref="console" />
    <appender-ref ref="file" />
  </root>
  <appender name="console" type="log4net.Appender.ConsoleAppender">
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date %level %logger - %message%newline" />
    </layout>
  </appender>
  <appender name="file" type="log4net.Appender.RollingFileAppender">
    <file value="DemoWebApiUnityLog4Net.log" />
    <appendToFile value="true" />
    <rollingStyle value="Size" />
    <maxSizeRollBackups value="5" />
    <maximumFileSize value="10MB" />
    <staticLogFileName value="true" />
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date [%thread] %level %logger - %message%newline" />
    </layout>
  </appender>
</log4net>

I have added this line to AssemblyInfo.cs

[assembly: log4net.Config.XmlConfigurator(ConfigFile = @"log4net.config", Watch = true)]

The log4net was registered in to the Unity container in UnityConfig.cs with this line:

container.AddNewExtension<Log4NetExtension>();

The full demo project can be found here: https://github.com/CarmonColvin/DemoWebApiUnityLog4Net

Nothing I have tried has resulted in a successful log. Any help is appreciated.


Solution

  • According to the log4net FAQ:

    If you are configuring log4net by specifying assembly level attributes on your assembly then the configuration will be loaded once the first call to the LogManager.GetLogger is made. It is necessary that the first call to LogManager.GetLogger made during the process (or AppDomain) is made from the assembly that has the configuration attributes. Log4net will look only once and only on the first calling assembly for the configuration attributes.

    So it sounds to me like you should be calling LogManager.GetLogger() in Global.asax when the application starts in order to load your configuration. Something like:

    using log4net;
    
    protected void Application_Start(object sender, EventArgs e)
    {
        var logger = LogManager.GetLogger(typeof(Global));
        logger.Info("Application started.");
    }