3

I have been trying to log the error in my .Net website to the SQL database using Log4Net AdoNetAppender, but the error message are not getting logged in the database. Looks like the AdoNetAppender is not getting enabled or read. While debugging what I observed is that the Logger.Log shows all its properties values as false. i.e. IsErrorEnabled / IsDebugEnabled / IsFatalEnabled / IsInfoEnabled / IsWarnEnabled all as false.

Version of the log4net.dll I am using is 2.0.8.0

click here to view image of object properties

The logging.cs code is as below:

[assembly: log4net.Config.XmlConfigurator(Watch = true)]
namespace Utility.Library
{
    public class Logging
    {

        public static class Logger
        {
            public static ILog Log = LogManager.GetLogger(typeof(SharedMethods));
        }

        public static class LogException
        {

            private static StringBuilder sessionJobLogBuilder = new StringBuilder();

            public static void LogError(string sMsg, Exception ex)
            {

                Logger.Log.Error(sMsg, ex);
                sessionJobLogBuilder.AppendLine(sMsg + Environment.NewLine);
                sessionJobLogBuilder.AppendLine(ex.ToString() + Environment.NewLine);

            }

            public static void LogInfo(string sMsg)
            {
                Logger.Log.Info(sMsg);
                sessionJobLogBuilder.AppendLine(sMsg + Environment.NewLine);
            }

        }

    }

}

And below is the app.config:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
  </configSections>
  <log4net>
    <appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
      <bufferSize value="1" />
      <connectionType value="System.Data.SqlClient.SqlConnection, 
   System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
      <connectionString value="data source=xxx\xxx;
    initial catalog=xxx;integrated security=false;
    persist security info=True;User ID=xxx;Password=xxx" />
      <commandText value="EXECUTE [dbo].[WriteLogEntry] @App, @Module, @Ver, @Computer, @UserID, @Level, @Message, @Exception" />
      <parameter>
        <parameterName value="@App" />
        <dbType value="String" />
        <size value="30" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%App" />
        </layout>
      </parameter>
      <parameter>
        <parameterName value="@Module" />
        <dbType value="String" />
        <size value="200" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%Module" />
        </layout>
      </parameter>
      <parameter>
        <parameterName value="@Ver" />
        <dbType value="String" />
        <size value="20" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%Ver" />
        </layout>
      </parameter>
      <parameter>
        <parameterName value="@Computer" />
        <dbType value="String" />
        <size value="15" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%Computer" />
        </layout>
      </parameter>
      <parameter>
        <parameterName value="@UserID" />
        <dbType value="String" />
        <size value="30" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%UserID" />
        </layout>
      </parameter>
      <parameter>
        <parameterName value="@Level" />
        <dbType value="Int32" />
        <layout type="log4net.Layout.PatternLayout" />
      </parameter>
      <parameter>
        <parameterName value="@Message" />
        <dbType value="String" />
        <size value="2000" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%Message" />
        </layout>
      </parameter>
      <parameter>
        <parameterName value="@Exception" />
        <dbType value="String" />
        <size value="2000" />
        <layout type="log4net.Layout.ExceptionLayout" />
      </parameter>
    </appender>
    <root>
      <level value="ALL" />
      <appender-ref ref="AdoNetAppender"/>
    </root>
  </log4net>
</configuration>

But the Logger.Log properties at all levels show as false.

Prem
  • 109
  • 1
  • 9
  • It's a website; do you mean `web.config` instead of `app.config`? – pfx Dec 06 '18 at 20:53
  • @pfx I have these two files logging.cs and app.config defined in a classs library and its dll been imported into my website. – Prem Dec 06 '18 at 20:57
  • Sure I will update my question with its version, I see it to be 2.0.8.0 in the log4net.dll properties – Prem Dec 06 '18 at 22:29

1 Answers1

0

From your comment I read you have a separate app.config file and the Logger class defined in a separate assembly.

An ASP.NET website only considers the web.config file.
Your app.config file doesn't get loaded, so the Log4net configuration doesn't get applied.

One way to solve this is to transform your app.config file into a separate Log4netconfiguration file and to load that explicitly.

  1. Move the <log4net> ... </log4net> content from the app.config file to a separate file (by convention named Log4net.config) in the root of your website project.
    The <log4net> element must be the root xml element in that file.

  2. Remove the [assembly: log4net.Config.XmlConfigurator(Watch = true)] from your Logger project.

  3. Add the following code to Application_Start in Global.asax of the website project to ensure that the log4net configuration gets loaded at website startup phase.

    void Application_Start(object sender, EventArgs e)    
    {
        ILoggerRepository repository = log4net.LogManager.GetRepository(Assembly.GetExecutingAssembly());
        XmlConfigurator.Configure(repository, new FileInfo(Server.MapPath("log4net.config")));
    
        // Remaining startup code.
    }
    

I have the following log4net.config in the root of my website project (near web.config) with just a RollingFileAppender but the concept is the same.

<log4net>
    <appender name="file" type="log4net.Appender.RollingFileAppender">
        <param name="ImmediateFlush" value="true" />
        <file value="Log.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>
    <root>
        <level value="ERROR" />
        <appender-ref ref="file" />
    </root>
</log4net>


With your AdoNetAppender setup in my Log4net.config the expected values for IsDebugEnabled, IsErrorEnabled, etc. get shown.


Summary:
Log4net's internal debug logging showed that the configuration file was not being loaded from the presumed location.
The combination of correcting this location (in the XmlConfigurator.Configure method call) and providing a configuration as shown above solved the problem.
pfx
  • 20,323
  • 43
  • 37
  • 57
  • I still see no change in the Logger.log properties as they still show as false. If possible kindly include your sample log4net.Appender.AdoNetAppender code, which I can strictly follow and figure out where the problem is. Thanks – Prem Dec 06 '18 at 22:47
  • Can you enable the Log4net’s internal debugging as explained at https://logging.apache.org/log4net/release/faq.html and provide the output? – pfx Dec 07 '18 at 11:45
  • The first change after making some change related to log4net, I did add the internal debugging as mentioned in the link and got the below text written into the C:\tmp\log4net.txt – Prem Dec 07 '18 at 13:39
  • ** I'm not really sure why the application at runtime is looking for log4net.config in this location ** log4net: config file [C:\Program Files (x86)\Common Files\Microsoft Shared\DevServer\10.0\log4net.config] not found. Configuration unchanged. – Prem Dec 07 '18 at 14:00
  • Bizarre, although almost surely the result of `Server.MapPath`. Please place the `log4net.config` at that location, or replace `Server.MapPath` with a fixed path, in order to find out whether the configuration gets loaded. Root cause of the problem seems to be in the configuration not being loaded. – pfx Dec 07 '18 at 14:40
  • Well for now I did give the complete folder path for the log4net.config and you know what it worked, it shows all the properties values as true this time. Kudos to you for your assistance. – Prem Dec 07 '18 at 18:17
  • But in this process of setting up the log4net error handling, as you know I have setup the log4net.config detailing the stored procedure and its parameters,I was just wondering where am I supposed to pass these required parameters. And how can I set them. Currently for debugging sake I have set a try catch block on a 1/0, to test how the error is logged. In the catch I have the code ` Logging.LogException.LogError(this.Title + " Divided by zero", ex); ` and was wondering how does this call alone pass all the list of required parameters in the stored procedure. – Prem Dec 07 '18 at 18:23