Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Log4Net does not log from a class library

I am working on .NET Framework 4.0 using C# in Windows 7, and trying to log from a class library but it's not working. I'm running my application without errors, but also nothing happens to my log file, neither to my console.

So, here is my code:

This is my App.config file:

<?xml version="1.0"?>
<configuration>

  <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
  </configSections>


  <add key="log4net.config" value="config.log4net"/>

  <log4net>
    <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date{ABSOLUTE} [%thread] %level %logger - %message%newlineExtra Info: %property{testProperty}%newline%exception"/>
      </layout>
      <filter type="log4net.Filter.LevelRangeFilter">
        <levelMin value="DEBUG"/>
        <levelMax value="FATAL"/>
      </filter>
    </appender>
    <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
      <file value="MyLogFile.txt"/>
      <appendToFile value="true"/>
      <rollingStyle value="Size"/>
      <maxSizeRollBackups value="5"/>
      <maximumFileSize value="10MB"/>
      <staticLogFileName value="true"/>
      <filter type="log4net.Filter.StringMatchFilter">
        <stringToMatch value="debug"/>
      </filter>
      <filter type="log4net.Filter.StringMatchFilter">
        <stringToMatch value="error"/>
      </filter>
      <filter type="log4net.Filter.DenyAllFilter"/>
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date [%thread] %level %logger - %message%newline%exception"/>
      </layout>
    </appender>
    <root>
      <level value="DEBUG"/>
      <appender-ref ref="ConsoleAppender"/>
      <appender-ref ref="RollingFileAppender"/>
    </root>
    <logger name="MyApplication">
      <level value="DEBUG"/>
      <appender-ref ref="ConsoleAppender"/>
      <appender-ref ref="RollingFileAppender"/>
    </logger>
  </log4net>

  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
  </startup>

</configuration>

This is what I put into my AssemblyInfo.cs:

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

This what is at the file i'm trying to log:

private static readonly ILog log = LogManager.GetLogger(
System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);


log.Debug("Testing");

When i run my program nothing happens. Someone knows why?

like image 987
Vinicius Seganfredo Avatar asked Nov 13 '13 17:11

Vinicius Seganfredo


People also ask

Does log4net work with .NET 5?

log4net works with almost any version of . NET (including . NET Core).

Is log4net structured logging?

log4net doesn't support the concept of structured logging. Like shown in the conversionPattern element in the XML configuration, you have some variables to play with when writing to the storage. But including properties like FirstName in the Serilog example isn't available.

Where do log4net logs go?

In your case, the log file will be in bin\Debug\netcoreapp3.


3 Answers

Similar to this answer, both the app.config, log4net configuration and the AssemblyInfo.cs configurator needs to be placed in the host application.

Lets say I have project Console as a console project that I will run, and Library as a Library project. Console will need to have an app.config file with the above log4net configuration, and the AssemblyInfo.cs will need the XmlConfigurator code inside of it. Library does not need either of these, and will work by using the LogManager call.

Console                 > This is the project that you will run.
    Properties
        AssemblyInfo.cs > Place [assembly: log4net.Config.XmlConfigurator(Watch = true)] here.
    app.config          > Place log4net XML configuration here.
    Program.cs          > Start of application.

Library
    Properties
        AssemblyInfo.cs > Leave this file alone.
    Foo.cs              > Create the private readonly property.
        SomeMethod()    > log.Debug("Test");
like image 175
matth Avatar answered Oct 08 '22 06:10

matth


Incase anyone is still looking at this and to add to the previous answers, you need to have instantiated a logger in your host application before you can log from the class library.

like image 26
sam.gregory91 Avatar answered Oct 08 '22 05:10

sam.gregory91


If you look at the log4net documentation for assembly attributes it says this:

"Therefore if you use configuration attributes you must invoke log4net to allow it to read the attributes. A simple call to LogManager.GetLogger will cause the attributes on the calling assembly to be read and processed. Therefore it is imperative to make a logging call as early as possible during the application start-up, and certainly before any external assemblies have been loaded and invoked."

When the assembly attributes are defined in a class library - i.e. an external assembly - it gets tricky. Can you use log4net.Config.XmlConfigurator.Configure(path) instead?

like image 39
stuartd Avatar answered Oct 08 '22 06:10

stuartd