1

I have a web application which uses log4net. My web application is deployed to Azure, and works there perfectly. However when I run it locally through VS2013 (update 4), log4net doesn't instantiate the AdoNetAppender.

I checked for exception by breaking on all thrown exceptions, nothing was thrown, I activated the internal log4net debugging and nothing exceptional showed in the debug output.

I also added <trust level="Full"/> to my web.config, nothing...

I'm stumped, again, it works on Azure, but not locally. Any ideas? Thanks!

EDIT Here's my web.config (relevant lines only)

<configuration>
  <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
  </configSections>
  <connectionStrings>
    <add name="DefaultConnection" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=**********;Integrated Security=SSPI" providerName="System.Data.SqlClient" />
  </connectionStrings>
  <log4net debug="true">
    <appender name="ADONetAppender" type="log4net.Appender.AdoNetAppender">
      <bufferSize value="1" />
      <connectionStringName value="DefaultConnection" />
      <commandText value="INSERT INTO Log ([StoreId],[Date],[Thread],[Level],[Logger],[Message],[Exception],[User]) VALUES (@store, @log_date, @thread, @log_level, @logger, @message, @exception, @user)" />
      <parameter>...</parameter>
      ...
    </appender>
    <appender name="DebugAppender" type="log4net.Appender.DebugAppender">
      <immediateFlush value="true" />
      <layout type="log4net.Layout.SimpleLayout" />
    </appender>
    <root>
      <level value="DEBUG" />
      <appender-ref ref="ADONetAppender" />
      <appender-ref ref="DebugAppender" />
    </root>
  </log4net>
  <appSettings>
    <add key="log4net.Internal.Debug" value="true" />
    <add key="log4net.Config" value="log4net.simple.config"/>
    <add key="log4net.Config.Watch" value="True"/>
  </appSettings>
  <system.web>
    <authentication mode="None" />
    <compilation debug="true" targetFramework="4.5.1" />
    <httpRuntime targetFramework="4.5.1" maxRequestLength="1048576" />
    <customErrors mode="Off" />
    <trust level="Full"/>
  </system.web>
</configuration>

UPDATE 2

I discovered that although log4net is configured properly, calling LogManager.GetLogger("...") returns a logger with no appenders. However if I inspect the hierarchy further I can see my AdoNetAppender in there, and also when XmlConfigurator.Configure() runs it outputs the following log4net: Adding appender named [ADONetAppender] to logger [root]....

So the problem boils down to (and this happens locally only, not on production) that the object returned from LogManager.GetLogger(...) doesn't contain any appenders.

SOLVED

See accepted answer below. It turns out all I was really missing was a call to XmlConfigurator.Configure() in my Application_Start method. All the other 'evidence' I provided is normal behavior, and the reason I wasn't seeing any log messages locally was a slight unintentional difference between the log table schema between my local db and the production one.

Aviad P.
  • 32,036
  • 14
  • 103
  • 124
  • Can you show your local config – stuartd Apr 29 '15 at 15:17
  • Could it be permissions? Have you run with a SQL profiler to see if any request is being made? – stuartd Apr 30 '15 at 11:05
  • No I haven't, but my web app can access my sql just fine, it's just the log4net which silently fails. Could it still be a permissions issue? By the way, my connection strings specifies `Integrated Security=SSPI` - isn't that ok? – Aviad P. Apr 30 '15 at 13:31
  • Running with a profiler would tell whether log4net is trying to write to the server at all. log4net will run in the same security context as the rest of the app so integrated security should be OK. – stuartd Apr 30 '15 at 13:56
  • Just noticed you're saying no appenders are *instantiated*, even though log4net is configured - so `LogManager.GetRepository().Configured` is true but `LogManager.GetRepository().GetAppenders()` is empty? It might be worth checking the output of `LogManager.GetRepository().ConfigurationMessages.Cast()` – stuartd Apr 30 '15 at 14:11
  • @stuartd found the problem, but don't know how to solve it. As it turns out `LogManager.GetRepository().Configured` was false, I called `XmlConfigurator.Configure()` manually and the appender was instantiated properly. However when running in Azure, log4net is initialized at a much earlier step, and I need it to happen locally too... – Aviad P. Apr 30 '15 at 22:37

1 Answers1

2

You can configure log4net in the Global.asax:

public class WebApiApplication : HttpApplication
{
    protected void Application_Start()
    {
        XmlConfigurator.Configure();

This works for azure and local.

Peter
  • 27,590
  • 8
  • 64
  • 84
  • That is too late for me, I am using this declaration in my classes: `private static readonly log4net.ILog log = log4net.LogManager.GetLogger (MethodBase.GetCurrentMethod().DeclaringType.ToString().Split('.').Last());` and these guys get called before `Application_Start`. So on Azure everything is ok, but locally they are called before `log4net` is configured. – Aviad P. May 01 '15 at 16:35
  • Looks like I was interpreting the evidence in the wrong way. Apparently locally you have to call `XmlConfigurator.Configure()` explicitly, but on Azure you don't. Also I had a misconfiguration issue which prevented me from seeing logs on my own machine (slightly different table schema between my local db and Azure's). – Aviad P. May 02 '15 at 09:19