Log4Net多个记录器

19
首先,我已经看到其他话题中的许多答案和提示(最相似的:Log4Net: Multiple loggers),但没有适用的答案。 我想要有两个具有不同文件附加器的记录器,并限制每个记录器都只能写入根记录器。 这是控制台应用程序。 全部代码如下:
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();
    }       
}
}

还有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>
      <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>

并在控制台输出:

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

文件已经被创建,但它们都是空的。当我在根目录中指定附加器时,如下所示:

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

然后,控制台输出:

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

仅在 AsyncTest.log 中出现:

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

我做错了什么?

更新(2014年10月21日):使用最新的Nuget可用的log4net,我得到了以下控制台输出:

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

两个文件(AsyncTest.log、SyncTest.log)都是空的。

UPD (08/4/2015): 解决方案是在log4net部分中设置所有属性时使用小写。因此,我只需要更改app.config中的以下行:

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

注意区别:属性'name'是小写的。


为了解决问题,我需要读完你的问题。小写字母问题。 - Abin
2个回答

23

你的样例中有几个拼写错误。首先是你没有关闭配置标签,而且为什么只能在一个文件中获取,是因为你调用了:

logger.Info("started async");

然后你意外地做了这件事:

logger.Info("started sync");

你不会在第二个文件中得到任何写入,因为你实际上没有将其记录。

从你的代码中,在控制台上我得到:

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

关于未来的信息,您做得很正确,将可添加性设置为false,因为这意味着记录器不会从根记录器继承。至于这个声明:

我想有两个具有不同文件附加器的记录器,并限制每个记录器写入根记录器

我不理解它。如果您希望您的记录器写入这些文件,同时根记录器例如拥有一个控制台附加器,只需删除可添加性,它们将写入控制台和自己的文件。也经过测试,效果非常好。

我已经阅读了您的评论。现在我添加了我正在使用的代码并获得了您需要的内容:

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

并且 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版本:1.2.13.0,支持.NET 4.0 请告诉我是否得到想要的结果。


XMight,感谢您的回复。错别字不会影响应用程序,只是我的帖子(无论如何-已经修复)。我从之前在这里发布的代码中重新创建了项目,并使用log4net 1.2.13.0,但它根本不起作用-两个文件都是空的(尽管我切换到logger2.Info("started sync");)。此外,在两个记录器中仅列出“FileInfoAppenderA”。为了澄清我的目标:1)需要logger1->仅记录到asyng.log中2)需要logger2->仅记录到sync.log中。3)不应将logger1或logger2记录到根记录器中(无论注册了什么)。 - LaoR
终于找到问题所在了,你会笑的。你看到我这个 '<logger Name="Sync" additivity="false">' 和你的 '<logger name="Sync" additivity="false">' 之间的区别了吗?是的,只是大小写敏感的属性名称 'name != Name'。这就是为什么我的记录器没有记录到正确的文件中,而且它们两个都是空的。 - LaoR
我很高兴你找到了问题 ;) - XMight

0

这个配置在我的电脑上可以正常工作:

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

祝你好运!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接