0
votes

I have a problem using log4net logging library.

There are 3 projects.

  1. .Net Core v2.2 WebAPI (log4net library added, log4net.config added) - uses the below class libraries
  2. .Net Standard v2.0 Class Library (log4net library added)
  3. .Net Standard v2.0 Class Library (log4net library added)

In project 1, in Startup.cs the log4net is started using following code:

loggerFactory.AddLog4Net("log4net.config", true);

the log4net.config file is the following:

<log4net>
      <appender name="LogsOnly" type="log4net.Appender.RollingFileAppender">
        <lockingModel type="log4net.Appender.FileAppender+MinimalLock"/>
        <file value="InfoLogs/" />
        <datePattern value="yyyy-MM-dd'.log'" />
        <staticLogFileName value="false" />
        <appendToFile value="true" />
        <rollingStyle value="Composite" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%date{yyyy-MM-dd HH:mm:ss.fff} [%thread] [%property{Context}] %-5level %logger - %message%newline" />
        </layout>
        <filter type="log4net.Filter.LevelRangeFilter">
          <levelMin value="DEBUG" />
          <levelMax value="WARN" />
        </filter>
        <filter type="log4net.Filter.DenyAllFilter" />
      </appender>
    <appender name="DebugOnly" type="log4net.Appender.RollingFileAppender">
    <threshold value="OFF" />
    <lockingModel type="log4net.Appender.FileAppender+MinimalLock"/>
    <file value="DebugLogs/" />
    <datePattern value="yyyy-MM-dd'.log'" />
    <staticLogFileName value="false" />
    <appendToFile value="true" />
    <rollingStyle value="Composite" />
    <layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="%date{yyyy-MM-dd HH:mm:ss.fff} [%thread] [%property{Context}] %-5level %logger - %message%newline" />
    </layout>
    <filter type="log4net.Filter.LevelRangeFilter">
    <levelMin value="DEBUG" />
    <levelMax value="DEBUG" />
    </filter>
    <filter type="log4net.Filter.DenyAllFilter" />
    </appender>
      <root>
        <appender-ref ref="LogsOnly" />
      </root>
    <logger name="DebugOnlyLogger">
    <log4net>
    <appender name="LogsOnly" type="log4net.Appender.RollingFileAppender">
        <lockingModel type="log4net.Appender.FileAppender+MinimalLock"/>
        <file value="InfoLogs/"/>
        <datePattern value="yyyy-MM-dd'.log'"/>
        <staticLogFileName value="false"/>
        <appendToFile value="true"/>
        <rollingStyle value="Composite"/>
        <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%date{yyyy-MM-dd HH:mm:ss.fff} [%thread] [%property{Context}] %-5level %logger - %message%newline"/>
        </layout>
        <filter type="log4net.Filter.LevelRangeFilter">
            <levelMin value="DEBUG"/>
            <levelMax value="WARN"/>
        </filter>
        <filter type="log4net.Filter.DenyAllFilter"/>
    </appender>
    <appender name="DebugOnly" type="log4net.Appender.RollingFileAppender">
        <threshold value="OFF"/>
        <lockingModel type="log4net.Appender.FileAppender+MinimalLock"/>
        <file value="DebugLogs/"/>
        <datePattern value="yyyy-MM-dd'.log'"/>
        <staticLogFileName value="false"/>
        <appendToFile value="true"/>
        <rollingStyle value="Composite"/>
        <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%date{yyyy-MM-dd HH:mm:ss.fff} [%thread] [%property{Context}] %-5level %logger - %message%newline"/>
        </layout>
        <filter type="log4net.Filter.LevelRangeFilter">
            <levelMin value="DEBUG"/>
            <levelMax value="DEBUG"/>
        </filter>
        <filter type="log4net.Filter.DenyAllFilter"/>
    </appender>
    <root>
        <appender-ref ref="LogsOnly"/>
    </root>
    <logger name="DebugOnlyLogger">
        <level value="DEBUG"/>
        <appender-ref ref="DebugOnly"/>
    </logger>
</log4net>

    </logger>
</log4net> 

In class libraries, the ILog instances are set using the following code:

var log4net.ILog log = log4net.LogManager.GetLogger("DebugOnlyLogger");

By this configuration:

  • The appender LogsOnly works during logging on WebAPI project.
  • The appender DebugOnly also works in class libraries.

What my problem is, I want to switch off logging for DebugOnlyLogger by changing the log4net.config file as following:

<logger name="DebugOnlyLogger">
    <level value="OFF" />
    <appender-ref ref="DebugOnly" />
</logger>

But the change is not recognized by loggers in class libraries, even though log4net is started with parameter watch = true (See AddLog4Net("log4net.config", true)). The loggers in class libraries keep logging in DEBUG level.

What am I missing? I tried several things like these, but they didn't solve the problem:

  • Reloading and reconfiguring in class libraries by using log4net.Config.XmlConfigurator.Configure() method.
  • Triggering RaiseConfigurationChanged event before logging in class libraries.
  • setting Threshold=OFF in DebugOnly appender.

I don't want to implement a quick and dirty solution by introducing a separate custom config file in each class libraries. The correct solution should be achieved by using only log4net.config file, but how?

1

1 Answers

0
votes

After careful inspection, the problem is resolved with the following change in Startup.cs

loggerFactory.AddLog4Net(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "log4net.config"), true);