具有类似日志根名称的log4net logger层次结构

时间:2011-04-21 01:21:24

标签: .net logging log4net hierarchy appender

我在这里发现了一个错误,或者我是否在使用此配置时出错?

<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
  <layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="%message%newline" />
  </layout>
</appender>
<logger name="MyApp.Common">
  <level value="WARN" />
  <appender-ref ref="ConsoleAppender" />
</logger>
<logger name="MyApp.Common.Namespace.SomeGenericClass`1">
  <level value="INFO" />
  <appender-ref ref="ConsoleAppender" />
</logger>

假设我已根据标准的“... DeclaringType”命名方案命名我的记录器,我的期望是MyApp.Common命名空间下的所有东西都会记录到控制台,只要它是WARN或更高。 SomeGenericClass`1中的任何内容都将被记录,如果它是INFO或更高(如果由于WARN记录器,则为WARN或更高时两次)。

发生的事情是SomeGenericClass`1中记录在INFO中的任何内容都将通过管道输出两次,而不是预期的一次。如果我删除更具体的记录器,则不会记录任何内容,如果我删除不太具体的记录器,则事情只记录一次,两者都是预期的。另外,在配置文件中反转记录器的顺序什么都不做(正如我所料,因为我猜这个顺序无关紧要。)

我在这里发现了一个错误,或者我错过了层次结构如何工作的重要内容?

2 个答案:

答案 0 :(得分:2)

我使用多个记录器节点的实验经验是log4net将使用您在任何特定记录器中设置的最低级别。因此,即使您在MyApp.Common中指定了WARN,在MyApp.Common.SomeGenericClass中使用INFO也会导致全局(?)级别设置降至WARN。所以你从MyApp.Common和MyApp.Common.SomeGenericClass获得了一个条目,因为appender ConsoleAppender被解雇了两次。

我所追求的是获取日志的子集以转到单独的文件。不完全是你在问你的问题,但它确实涵盖了你想做的事情。而且我确实希望在某个地方记录我的解决方案,我可以为了自己的利益再次找到它;-)。

我创建了两个不同的记录器,例如你上面的记录器,虽然一个是root,它的工作方式是相同的。然后我创建了两个不同的appender,每个appender在不同的错误级别上进行过滤,并在两个记录器中分别引用它们。我得到的是一个文件中的OtherNamespace和另一个文件中的所有其他日志。代码如下。

<log4net>
<logger name="OtherNamespace">
  <appender-ref ref="OtherNamespaceAppender"/>
</logger>
<root>
  <level value="WARN"/>
  <appender-ref ref="MyRollingFileAppender"/>
</root>
<appender name="MyRollingFileAppender" type="log4net.Appender.RollingFileAppender">
  <file type="log4net.Util.PatternString" value="C:\Comanche\mylogfileFor_%property{User}.log" />
  <appendToFile value="true" />
  <rollingStyle value="Size" />
  <threshold value="ERROR" />
  <countDirection value="3" />
  <maxSizeRollBackups value="2" />
  <maximumFileSize value="200KB" />
  <staticLogFileName value="true" />
  <layout type="log4net.Layout.PatternLayout">
    <param name="ConversionPattern" value="%-6level%utcdate{ABSOLUTE} – %location :: %message%newline" />
  </layout>
</appender>
<appender name="OtherNamespaceAppender" type="log4net.Appender.RollingFileAppender">
  <file value="C:\Comanche\OtherNamespace.log" />
  <appendToFile value="true" />
  <rollingStyle value="Size" />
  <threshold value="WARN" />
  <countDirection value="3" />
  <maxSizeRollBackups value="2" />
  <maximumFileSize value="200KB" />
  <staticLogFileName value="true" />
  <filter type="log4net.Filter.LoggerMatchFilter">
    <acceptOnMatch value="true" />
    <LoggerToMatch value="OtherNamespace" />
    <!-- set your class name here -->
  </filter>

  <filter type="log4net.Filter.DenyAllFilter" />

  <layout type="log4net.Layout.PatternLayout">
    <param name="ConversionPattern" value="%-6level%utcdate{ABSOLUTE} :: %message%newline" />
  </layout>
</appender>

请注意,“其他所有内容”都位于另一个名称空间中,因此它不会被分流到OtherNamespace记录器中,如果存在某种名称匹配,它可能具有该记录器。另请注意,由于所有内容都从root继承,如果我将root引用的appender上的日志级别更改为WARN,我也会得到OtherNamespace日志。我想要实现的只是将更详细的日志记录转到与其他所有文件不同的文件。

答案 1 :(得分:0)

我认为这应该做你想要的(没有测试):

<logger name="MyApp.Common">
     <level value="WARN" />
     <appender-ref ref="ConsoleAppender" />
</logger>
<logger name="MyApp.Common.Namespace.SomeGenericClass`1">
     <level value="INFO" />  
</logger>

无需再次引用appender,除非您将additivity设置为false,否则它会自动继承。