Log4net - 修改单个记录器和追加器组合的日志记录级别

时间:2015-04-29 15:44:05

标签: log4net

我有两个appender,一个(InfoAppender)带有levelMin信息过滤器,一个(DebugAppender)没有过滤器。这非常有效。我还可以使用该元素为各个记录器设置最小日志记录级别。但是现在我想让大多数记录器将Info(及以上)信息记录到InfoAppender并调试(及以上)到DebugAppender,但是某个健谈记录器(NHibernate)记录警告(及以上)InfoAppender和info(及以上)到DebugAppender。

我查看了Log4Net Logging of two different levels to two different appenders for the same logger中提供的解决方案,但它对我不起作用。我有以下配置:

<log4net>
  <appender name="InfoAppender" type="log4net.Appender.RollingFileAppender">
    <file value="C:\Logs\" />
    <appendToFile value="true" />
    <rollingStyle value="Date" />
    <datePattern value="'Info.'yyyy-MM-dd'.log.txt'"/>
    <staticLogFileName value="false" />
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
    </layout>
    <filter type="log4net.Filter.LevelRangeFilter">
      <levelMin value="INFO" />
    </filter>
  </appender>
  <appender name="DebugAppender" type="log4net.Appender.RollingFileAppender">
    <file value="C:\Logs\" />
    <appendToFile value="true" />
    <rollingStyle value="Date" />
    <datePattern value="'Debug.'yyyy-MM-dd'.log.txt'"/>
    <staticLogFileName value="false" />
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
    </layout>
  </appender>
  <logger name="NHibernate" additivity="false">
    <appender-ref ref="InfoAppender">
      <threshold value="WARN" />
    </appender-ref>
    <appender-ref ref="DebugAppender">
      <threshold value="INFO" />
    </appender-ref>
  </logger>
  <root>
    <level value="DEBUG" />
    <appender-ref ref="InfoAppender" />
    <appender-ref ref="DebugAppender" />
  </root>
</log4net>

我有以下测试代码:

        XmlConfigurator.Configure();
        var logger1 = LogManager.GetLogger("Program");
        var logger2 = LogManager.GetLogger("NHibernate");
        logger1.Debug("Debug message");
        logger2.Debug("Debug message");
        logger1.Info("Info message");
        logger2.Info("Info message");
        logger1.Warn("Warn message");
        logger2.Warn("Warn message");

但是两个调试消息都记录到DebugAppender中,并且两个信息消息都记录到InfoAppender。

1 个答案:

答案 0 :(得分:1)

log4net的配置机制非常宽松,但没有考虑到何时不考虑某些参数。例如,在您的配置中,以下引用了appender InfoAppender,但阈值属性没有做任何事情

 <appender-ref ref="InfoAppender">
    <threshold value="WARN" />
  </appender-ref>

appender-ref节点下面没有解析xml元素,你可以把它赢得的任何内容都考虑在内:

protected void ParseChildrenOfLoggerElement(XmlElement catElement, Logger log, bool isRoot)
// some code ommited
        if (xmlElement.LocalName == "appender-ref")
        {
            IAppender appender = this.FindAppenderByReference(xmlElement);
            string attribute = xmlElement.GetAttribute("ref");
            if (appender != null)
            {
                LogLog.Debug(string.Concat(new string[]
                {
                    "XmlHierarchyConfigurator: Adding appender named [",
                    attribute,
                    "] to logger [",
                    log.Name,
                    "]."
                }));
                log.AddAppender(appender);
            }
            else
            {
                LogLog.Error("XmlHierarchyConfigurator: Appender named [" + attribute + "] not found.");
            }
        }

您需要做的是在记录器和最终的appender之间添加一个过滤器。为此,我建议使用ForwardingAppender,它允许您在appender之间传递日志事件,同时添加一些行为:将配置文件的NHibernate部分更改为:

<appender name="NHibernateDebugFilterAppender" type="log4net.Appender.ForwardingAppender">
  <appender-ref ref="DebugAppender"/>
  <filter type="log4net.Filter.LevelRangeFilter">
    <levelMin value="INFO" />
  </filter>
</appender>

<appender name="NHibernateInfoFilterAppender" type="log4net.Appender.ForwardingAppender">
  <appender-ref ref="InfoAppender"/>
  <filter type="log4net.Filter.LevelRangeFilter">
    <levelMin value="WARN" />
  </filter>
</appender>

<logger name="NHibernate" additivity="false">
  <appender-ref ref="NHibernateInfoFilterAppender" />
  <appender-ref ref="NHibernateDebugFilterAppender"/>
</logger>