Sebastian Müller
Sebastian Müller

Reputation: 5589

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?

Upvotes: 22

Views: 43936

Answers (3)

RBT
RBT

Reputation: 25897

I believe the file that you've mentioned in your post is the content of App.config file instead. App.config is the default configuration file for a variety of C# project templates like WinForm application, Console application, etc. So you should consider naming it as App.config in place of Log4Net.config.

In order to have a full fledged understanding, let us go through three possible ways of configuring log4net:

  1. If we want to use our application's App.config file to hold the settings of log4net, then we'll have to add the below mentioned declaration in AssemlyInfo.cs file to below line:

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

    App.config will hold the log4net settings like this:

     <?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>
    
  2. In some scenario, we might want to use a dedicated file for holding settings of log4net. We can name it e.g. log4net.config or log4net.xml. While creating such a dedicated config file, we need to ensure that log4net is the root tag of the config file (Refer file-snippet):

    <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, we require following declaration in AssemblyInfo.cs file. Same declaration has been mentioned in the OP's question also:

    [assembly: log4net.Config.XmlConfigurator(ConfigFile = "Log4Net.config", Watch = true)]
    
  3. Now the final use-case. Let's say we're having a custom xml file of our own e.g. myCustomSettings.xml which contains log4net setting. In this case log4net tag is present in a custom config file but it is not the root tag of that file (Refer file-snippet)

    <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 we'll have to configure log4net through C# code at run-time (Refer code-snippet).

     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);
    

    In this case we don't require the declarative configuration in AssemblyInfo.cs file. So please make sure that you've removed it from there:

     //TODO: Remove it
     [assembly: log4net.Config.XmlConfigurator(Watch = true)]
    

Upvotes: 7

nithinmohantk
nithinmohantk

Reputation: 457

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.

Upvotes: 23

Peter Lillevold
Peter Lillevold

Reputation: 33920

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.

Upvotes: 22

Related Questions