Log4Net Multiple loggers
Asked Answered
A

2

19

First of all, I have seen a lot of answers and tips in others topics (most similar: Log4Net: Multiple loggers), but there is no applicable answer.

I want to have 2 loggers with different file appenders and restrict each to write into root logger. It is Console app. Whole code below:

using System;
using System.Diagnostics;
using System.Linq;
using log4net;

namespace Test_log4net
{
class Program
{
    static void Main(string[] args)
    {
        log4net.Config.XmlConfigurator.Configure();
            ILog logger = LogManager.GetLogger("Async");
        logger.Info("started async");
        Console.WriteLine("Logger: {0}", (logger as log4net.Core.LogImpl).Logger.Name);
        Console.WriteLine("Appenders: {0}", string.Join(", ", (logger as log4net.Core.LogImpl).Logger.Repository.GetAppenders().ToList().Select(appendr => appendr.Name)));

        ILog logger2 = LogManager.GetLogger("Sync");
        logger2.Info("started sync"); //changed: from logger -> to logger2 on 10/21/2014
        Console.WriteLine("Logger: {0}", (logger2 as log4net.Core.LogImpl).Logger.Name);
        Console.WriteLine("Appenders: {0}", string.Join(", ", (logger2 as log4net.Core.LogImpl).Logger.Repository.GetAppenders().ToList().Select(appendr => appendr.Name)));

        Console.ReadKey();
    }       
}
}

And App.config file:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
   <configSections>
      <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
   </configSections>
   <startup>
      <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
   </startup>
   <log4net>
      <root>
         <level value="All"/>
      </root>

      <appender name="FileInfoAppenderA" type="log4net.Appender.RollingFileAppender">
         <file value="D:\\temp\\AsyncTest.log"/>
         <filter type="log4net.Filter.LevelRangeFilter">
            <levelMin value="DEBUG"/>
            <levelMax value="FATAL"/>
         </filter>
         <appendToFile value="true"/>
         <rollingStyle value="Size"/>
         <maxSizeRollBackups value="10"/>
         <maximumFileSize value="100MB"/>
         <staticLogFileName value="true"/>
         <datePattern value="yyyyMMdd"/>
         <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%d - %m%n"/>
         </layout>
      </appender>

      <appender name="FileInfoAppenderS" type="log4net.Appender.RollingFileAppender">
         <file value="D:\\temp\\SyncTest.log"/>
         <filter type="log4net.Filter.LevelRangeFilter">
            <levelMin value="DEBUG"/>
            <levelMax value="FATAL"/>
         </filter>
         <appendToFile value="true"/>
         <rollingStyle value="Size"/>
         <maxSizeRollBackups value="10"/>
         <maximumFileSize value="100MB"/>
         <staticLogFileName value="true"/>
         <datePattern value="yyyyMMdd"/>
         <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%d - %m%n"/>
         </layout>
      </appender>

      <logger Name="Sync" additivity="false">
         <level value="INFO"/>
         <appender-ref ref="FileInfoAppenderS"/>
      </logger>

      <logger Name="Async" additivity="false">
         <level value="INFO"/>
         <appender-ref ref="FileInfoAppenderA"/>
      </logger>
        
   </log4net>
</configuration>

And console output:

    Logger: Async
    Appenders: FileInfoAppenderA
    Logger: Sync
    Appenders: FileInfoAppenderA

Files have been created, but both of them are empty. When I specify appenders in root, like:

<root>
    <level value="All"/>
    <appender-ref ref="FileInfoAppenderA"/>
    <appender-ref ref="FileInfoAppenderS"/>
</root>

then, console:

log4net:ERROR [RollingFileAppender] Attempted to append to closed appender named [FileInfoAppenderS]
Logger: Async
Appenders: FileInfoAppenderA, FileInfoAppenderS
Logger: Sync
Appenders: FileInfoAppenderA, FileInfoAppenderS

And only in AsyncTest.log:

2014-04-11 17:26:58,142 - started async
2014-04-11 17:26:58,151 - started sync

What I am doing wrong?

UPD (10/21/2014): With latest log4net available via Nuget I have following console output:

Logger: Async
Appenders: FileInfoAppenderA
Logger: Sync
Appenders: FileInfoAppenderA

And both of files (AsyncTest.log, SyncTest.log) are empty.

UPD (08/4/2015): Solution is to use lower case when setting the attributes for everything in log4net section. So, I just should have changed following lines in app.config:

......
<logger name="Sync" additivity="false">
......
<logger name="Async" additivity="false">
......

Note the difference: attribute 'name' is in lower case.

Acropolis answered 11/4, 2014 at 14:31 Comment(1)
for solution i need to read till the end of your Question. lower case issue.Afterburning
L
23

You have several typos on your example. First is you don't close the configuration tag, and why you're getting only in one file, is because you call:

logger.Info("started async");

and after that you surprisingly do:

logger.Info("started sync");

You will not get writing in the second file because you actually don't log to it.

And in console I get from your code:

Logger: Async
Appenders: FileInfoAppenderS, FileInfoAppenderA
Logger: Sync
Appenders: FileInfoAppenderS, FileInfoAppenderA

For future information, you did correctly by putting additivity to false, because this means that the loggers will not inherit from root logger. As about the statement:

I want to have 2 loggers with different file appenders and restrict each to write into root logger

I do not understand it. If you want that your loggers write to these files while root logger having a console appender for example, just remove additivity and they will write to console and their own files. Also tested and it works very well.

I have read your comment. Now I add the code that I'm using and getting what you need:

class Program
{
    static void Main(string[] args)
    {
        log4net.Config.XmlConfigurator.Configure();

        ILog logger = LogManager.GetLogger("Async");
        logger.Info("started async");
        Console.WriteLine("Logger: {0}", (logger as log4net.Core.LogImpl).Logger.Name);
        Console.WriteLine("Appenders: {0}", string.Join(", ", (logger as log4net.Core.LogImpl).Logger.Repository.GetAppenders().ToList().Select(appendr => appendr.Name)));


        ILog logger2 = LogManager.GetLogger("Sync");
        logger2.Info("started sync");
        Console.WriteLine("Logger: {0}", (logger2 as log4net.Core.LogImpl).Logger.Name);
        Console.WriteLine("Appenders: {0}", string.Join(", ", (logger2 as log4net.Core.LogImpl).Logger.Repository.GetAppenders().ToList().Select(appendr => appendr.Name)));

        Console.ReadKey();
    }
}

And the app.config:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
    </configSections>
    <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
    <log4net>
        <appender name="FileInfoAppenderA" type="log4net.Appender.RollingFileAppender">
          <file value="C:\\temp\\AsyncTest.log"/>
          <filter type="log4net.Filter.LevelRangeFilter">
            <levelMin value="DEBUG"/>
            <levelMax value="FATAL"/>
          </filter>
          <appendToFile value="true"/>
          <rollingStyle value="Size"/>
          <maxSizeRollBackups value="10"/>
          <maximumFileSize value="100MB"/>
          <staticLogFileName value="true"/>
          <datePattern value="yyyyMMdd"/>
          <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%d - %m%n"/>
          </layout>
        </appender>
    
        <appender name="FileInfoAppenderS" type="log4net.Appender.RollingFileAppender">
            <file value="C:\\temp\\SyncTest.log"/>
            <filter type="log4net.Filter.LevelRangeFilter">
                <levelMin value="DEBUG"/>
                <levelMax value="FATAL"/>
            </filter>
            <appendToFile value="true"/>
            <rollingStyle value="Size"/>
            <maxSizeRollBackups value="10"/>
            <maximumFileSize value="100MB"/>
            <staticLogFileName value="true"/>
            <datePattern value="yyyyMMdd"/>
            <layout type="log4net.Layout.PatternLayout">
                <conversionPattern value="%d - %m%n"/>
            </layout>
        </appender>
    
        <root>
            <level value="INFO"/>
        </root>
        
        <logger name="Sync" additivity="false">
            <level value="INFO"/>
            <appender-ref ref="FileInfoAppenderS"/>
        </logger>
    
        <logger name="Async" additivity="false">
            <level value="INFO"/>
            <appender-ref ref="FileInfoAppenderA"/>
        </logger>
    </log4net>
</configuration>

Log4net version: 1.2.13.0 with .NET 4.0 Tell me please if you get what you want.

Lunik answered 30/9, 2014 at 14:30 Comment(3)
XMight, thx for replay. Typos does not affect application, just my post (anyway - fixed). I've recreated project from code I had posted here before and with log4net 1.2.13.0 it does not work at all - both of files are empty (despite I switched to logger2.Info("started sync");). Moreover, only "FileInfoAppenderA" is listed in both of loggers. And to clarify my goal: 1) need logger1 -> log into asyng.log ONLY 2) need logger2 -> log into sync.log ONLY. 3) Not logger1, not logger2 should log into root logger (whatever is registered there)Acropolis
finally I've got what was the problem) You will laugh) Do you see the difference between my '<logger Name="Sync" additivity="false">' and yours '<logger name="Sync" additivity="false">' ? Yes, is was just case sensitive attribute name 'name != Name'. That is why my loggers did not log into proper files and both of them were empty.Acropolis
I'm happy that you found the problem ;)Lunik
S
1

This configuration worked for me:

<log4net>
    <root name="EventLog">
        <level value="ALL"/>
        <appender-ref ref="EventLogAppender"/>
    </root>

    <logger name="FileLogger" additivity="false">
        <level value="ALL" />
        <appender-ref ref="RollingFileAppender" />
    
        ...appenders
    </logger>

Good Luck!

Stocktonontees answered 23/6, 2016 at 23:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.