log4net:配置以忽略来自特定类的消息

68

有没有一种方法可以使log4net配置忽略特定的类?例如,我们通常在每个类中创建一个日志。类似于这样:

private static readonly ILog Log = log4net.LogManager.GetLogger("MyClass");
问题是MyClass记录了极大量的数据,这使得查找其他类的信息变得困难。另一个开发人员使用了MyClass,因此我不能只是进入并更改日志文件,但在我的环境中,我想忽略这些信息。
我可以将configuration文件设置为忽略特定类别的消息吗?
5个回答

86

当然,可以使用过滤器

以下是博客中发布的代码片段,供以后参考 - 所有功劳归于该博客文章的作者:

<filter type="log4net.Filter.LoggerMatchFilter">
  <!-- allows this sub-namespace to be logged... -->
  <loggerToMatch value="Noisy.Namespace.But.Important" />
</filter>
<filter type="log4net.Filter.LoggerMatchFilter">
  <!-- ...but not the rest of it -->
  <loggerToMatch value="Noisy.Namespace" />
  <acceptOnMatch value="false" />
</filter>

60

使用过滤器确实可以解决问题,但我更喜欢直接关闭记录器(或记录器层次结构),如下所示:

<logger name="YourNameSpace.WithNoLogging" additivity="false">
    <level value="OFF" />        
</logger>
<logger name="MyClass" additivity="false">
    <level value="OFF" />        
</logger>
<root>
    <level value="ALL" />
    <appender-ref ref="YourAppender" />
</root>
假设 YourNameSpace.WithNoLogging 是一个命名空间,那么所示的配置将禁用整个命名空间的日志记录。第二个“例子”将根据您的问题关闭类的日志记录。

1
它能与第三方程序集一起使用吗?我正在尝试忽略RavenDb的消息,但迄今为止没有成功。 - chester89
1
我最终成功了 - 通过指定记录日志的类的完整名称,某种带有星号的命名空间并不能实现。 - chester89
Stefan,没错,那是在服务器端。 - chester89
嗨,我认为只有在每个类中使用getLogger(myclass)时,它才能正常工作。如果您在应用程序启动时生成了一个命名记录器,并在整个应用程序中通过引用使用它,则不起作用。或者我在这一点上是错误的吗? - swe
@swe:你说得对。我更喜欢为每个类使用不同的日志记录器,因为它提供了更多的灵活性。 - Stefan Egli
显示剩余3条评论

16

我建议也使用Filters。然而, 由于当我尝试实现筛选器时,我曾经苦苦挣扎找不到整个图片,所以我发布了一个 Configutation file 的示例片段,指出了筛选器放置的位置。

在这种情况下,您需要选择的筛选器是:

log4net.Filter.LoggerMatchFilter ----(匹配日志记录器名称的开头)

提示:Log4Netconfig文件中,放置标签的位置以及它们的优先级实际上很重要。因此,在这种情况下,<filter>标记出现在<appender>打开标记之后,并且在其<file value = ... />标记之前。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
    </configSections>
    <log4net>
        <appender name="RollingFile.PassedDevices" type="log4net.Appender.RollingFileAppender">
            <filter type="log4net.Filter.LoggerMatchFilter">
                <loggerToMatch value="Foo.namespace.bar.mySubclass" />
                <acceptOnMatch value="false" />
            </filter>
            <file value="myPassedDevices.log" />
            <appendToFile value="true" />
            <maximumFileSize value="100KB" />
            <maxSizeRollBackups value="2" />
            <layout type="log4net.Layout.PatternLayout">
                <conversionPattern value="%timestamp    %level  - %message  [%thread]       %logger%newline" />
            </layout>
        </appender>
        <root>
            <level value="DEBUG" />
            <appender-ref ref="RollingFile" /> <!-- My other appender which logs all and I cut it out in this snippet. Remember that you should reference all your appenders in this tag to make them work.-->
            <appender-ref ref="RollingFile.PassedDevices" />
        </root>
    </log4net>
</configuration>
在这种技术中,您可以拥有多个 appenders ,您可以将特定记录器的日志结果重定向到单独的 appender 而不是忽略它们。例如,为所有日志设置一个 appender ,并为特定 class 筛选出的日志设置另一个 appender

2

感谢您的提示。在我将过滤器移动到“文件值=…”之前,它并没有起作用。 - leem

1

如果您正在使用NHibernate和log4net,我想发布常见的排除方法。请注意,每个过滤器都需要自己的元素。

<filter type="log4net.Filter.LoggerMatchFilter">
    <loggerToMatch value="NHibernate.Engine.StatefulPersistenceContext.ProxyWarnLog" />
    <acceptOnMatch value="false" />
  </filter>
  <filter type="log4net.Filter.LoggerMatchFilter">
    <loggerToMatch value="NHibernate.LazyInitializationException" />
    <acceptOnMatch value="false" />
  </filter>
  <filter type="log4net.Filter.LoggerMatchFilter">
    <loggerToMatch value="NHibernate.Cache.NoCacheProvider" />
    <acceptOnMatch value="false" />
  </filter>

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