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.

Zoka
  • 2,312
  • 4
  • 23
  • 33
LaoR
  • 1,278
  • 1
  • 10
  • 19

2 Answers2

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.

AaA
  • 3,600
  • 8
  • 61
  • 86
XMight
  • 1,991
  • 2
  • 20
  • 36
  • 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) – LaoR Oct 21 '14 at 14:45
  • finally I've got what was the problem) You will laugh) Do you see the difference between my '' and yours '' ? 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. – LaoR Aug 04 '15 at 12:49
  • I'm happy that you found the problem ;) – XMight Aug 07 '15 at 12:22
0

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!

AaA
  • 3,600
  • 8
  • 61
  • 86
David Castro
  • 1,773
  • 21
  • 21