Configuring log4net with xml file

I tried to configure log4net for logging everything to the console output. I have a config file named Log4Net.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
  </configSections>
  <log4net>
    <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender" >
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date [%thread] %-5level %logger [%ndc] - %message%newline" />
      </layout>
    </appender>
    <root>
      <level value="INFO" />
      <appender-ref ref="ConsoleAppender" />
    </root>
  </log4net>
</configuration>

and I have my main class (just a testing case)

namespace TestLog4Net {
    class Program {
        private static readonly ILog log = LogManager.GetLogger(typeof(Program));

        static void Main(string[] args) {
            log.Info("Info");
            log.Error("Error");
            Console.ReadKey();
        }
    }
}

I added these lines to the AssemblyInfo.cs

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

But now nothing is logged, can someone explain this?


Solution 1:

When you have log4net config in a separate config file you should not include the configuration and configSections elements. log4net should be the top level element after the xml declartion.

Solution 2:

Try this custom configuration through code. Worked for me and tested in multiple apps..

string logFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "\\Config\\Log4Net.config");
    FileInfo finfo = new FileInfo(logFilePath);
   log4net.Config.XmlConfigurator.ConfigureAndWatch(finfo); 

I understand it's a very late reply. But will be useful for some right.

Solution 3:

I believe, the file that you've mentioned in your post is the content of App.config file instead. It is the default configuration file for a variety of C# desktop projects e.g. console application. So there are three cases possible in all:

  1. If you want to use app.config file to hold the settings of log4net then you'll have to change the declaration in AssemlyInfo.cs file to:

    [assembly: log4net.Config.XmlConfigurator(Watch = true)]

  2. In case you're using a dedicated settings file for log4net then you'll have to modify your Log4Net.config or Log4Net.xml file in a way that log4net is the root tag of the config file:

    <log4net>
         <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender" >
           <layout type="log4net.Layout.PatternLayout">
             <conversionPattern value="%date [%thread] %-5level %logger [%ndc] - %message%newline" />
           </layout>
         </appender>
         <root>
           <level value="INFO" />
           <appender-ref ref="ConsoleAppender" />
         </root>
       </log4net>
    

    In this case you can keep your declaration in AssemblyInfo.cs file as it is that you've mentioned in your post:

    [assembly: log4net.Config.XmlConfigurator(ConfigFile = "Log4Net.config", Watch = true)]
    
  3. Now the final use-case. Let's say you're having a custom xml file of your own e.g. myCustomSettings.xml which contains log4net setting. A sample is as below:

    <MyCustomSetting>
      <mySection1></mySection1>
      <mySection2></mySection2>
      <log4net>
         <root>
             <level value="ALL" />
             <appender-ref ref="file" />
             <appender-ref ref="console" />
         </root>
         <appender name="console" type="log4net.Appender.ConsoleAppender">
           <layout type="log4net.Layout.PatternLayout">
             <conversionPattern value="%date %level  - %message%newline" />
           </layout>
           <threshold value="Info" />
         </appender>
         <appender name="file" type="log4net.Appender.RollingFileAppender">
            <file value="${PROGRAMDATA}\MyProduct\myLogs.log" />
            <appendToFile value="true" />
            <rollingStyle value="Size" />
            <maxSizeRollBackups value="5" />
            <maximumFileSize value="10MB" />
            <staticLogFileName value="true" />
            <threshold value="Debug" />
            <layout type="log4net.Layout.PatternLayout">
                <conversionPattern value="%date [%thread] %level %logger - %message%newline" />
            </layout>
         </appender>
       </log4net>
     </MyCustomSetting>
    

    In such a case you'll have to configure log4net through C# code at run-time. Here is how you do it:

     using System.Xml;
    
     var configFilePath = "myCustomSettings.xml";
     var log4netConfig = new XmlDocument();
     log4netConfig.Load(File.OpenRead(configFilePath));
    
     var repo = LogManager.CreateRepository(Assembly.GetEntryAssembly(), typeof(log4net.Repository.Hierarchy.Hierarchy));
    
     var log4NetXml = log4netConfig["MyCustomSetting"]["log4net"];
     log4net.Config.XmlConfigurator.Configure(repo, log4NetXml);
    

    Please make sure that you remove the declarative configuration from AssemblyInfo.cs file in this particular case.