c# - log4net - 配置忽略来自特定线程的消息

标签 c# logging nunit log4net log4net-filter

是否有可能从特定线程中过滤掉日志条目?

我使用 nunit 运行测试 (c#):

using System;
using NUnit.Core;
using log4net;

namespace Main
{
    public class Program
    {
        public static readonly ILogger log = LogManager.GetLogger(typeof(Program));

        static void Main(string[] args)
        {
            log.Info("start");

            TestPackage package = new TestPackage(@"C:\Test\Main.Tests.dll");
            RemoteTestRunner remoteTestRunner = new RemoteTestRunner();
            remoteTestRunner.Load(package);
            TestResult result = remoteTestRunner.Run(new NullListener(), TestFilter.Empty, true, LoggingThreshold.All);

            log.Info("end");
        }
    }
}

这是我得到的日志:

INFO  17:57:24 [1] Main.Program - start
ERROR 17:57:25 [TestRunnerThread] Main.TestedClass - Exception! Relevant for production / okay in test
INFO  17:57:26 [1] Main.Program - end

每次记录错误时,log4net 都会向我发送一封邮件。如果我运行测试,我不想收到那些邮件。 nunit 将线程名称设置为:“TestRunnerThread”。如何忽略此线程?

我读过这个:How to log into separate files per thread with Log4Net?并尝试了这个过滤器(并没有得到任何日志):

<filter type="log4net.Filter.PropertyFilter">
    <key value="threadId" />
    <stringToMatch value="TestRunnerThread" />
    <acceptOnMatch value="false" />
</filter>

最佳答案

一些事情:

  • the answer 中所述至 the question您链接到,您必须使用 ThreadContext 注册一个键值对才能使过滤器键工作:ThreadContext.Properties["threadId"] = "1"
  • 过滤顺序很重要。来自docs :

    Filters form a chain that the event has to pass through. Any filter along the way can accept the event and stop processing, deny the event and stop processing, or allow the event on to the next filter. If the event gets to the end of the filter chain without being denied it is implicitly accepted and will be logged.

    确保过滤器顺序如下:

    1. 过滤您想要的线程
      • 如果匹配,则拒绝消息并且传递给下一个过滤器(由于<acceptOnMatch value="false" />
      • 如果不匹配,则将消息传递给链中的下一个过滤器
    2. 记录器过滤器
      • 如果匹配,消息被接受并且传递给下一个过滤器
      • 如果不匹配,则将消息传递给链中的下一个过滤器
    3. 全部拒绝
      • 消息被拒绝

完整示例:

<?xml version="1.0" encoding="utf-8"?>
<log4net>
    <appender type="log4net.Appender.ConsoleAppender" name="consoleApp">
        <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%message%newline" />
        </layout>       
        <filter type="log4net.Filter.PropertyFilter">
            <key value="threadId" />
            <stringToMatch value="3" />
            <acceptOnMatch value="false" />
        </filter>
        <filter type="log4net.Filter.LoggerMatchFilter">
            <loggerToMatch value="sandbox" />
        </filter>
        <filter type="log4net.Filter.DenyAllFilter" />
    </appender>
    <root>
        <level value="ALL" />
        <appender-ref ref="consoleApp" />
    </root>
</log4net>
static void Main(string[] args)
{
    XmlConfigurator.Configure(new FileInfo("config.xml"));

    ILog log = LogManager.GetLogger("sandbox");

    ThreadPool.QueueUserWorkItem(a =>
    {
        ThreadContext.Properties["threadId"] = "1";
        log.Debug("one");
    });

    ThreadPool.QueueUserWorkItem(a =>
    {
        ThreadContext.Properties["threadId"] = "2";
        log.Debug("two");
    });

    ThreadPool.QueueUserWorkItem(a =>
    {
        ThreadContext.Properties["threadId"] = "3";
        log.Debug("three");
    });

    Console.Read();
}

将记录:

one
two

(可能顺序不同,取决于哪个线程先完成)

关于c# - log4net - 配置忽略来自特定线程的消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12606223/

相关文章:

python - 用于 Python 应用程序的 Bluemix 日志记录

c# - 如何将 nunit 测试结果包含在 sonarcube 4.5.1 c# 插件 3.3 sonar-project.properties 文件中?

c# - 使用文件夹结构和 XML 文件在 NUnit 中动态生成测试夹具和测试用例

c# - 当文件的内容也带有希伯来字母时,如何使用 openFileDialog 打开文本文件?

c# - MVC 到 Azure Active Directory 登录回复 "Bad Request"和消息 "Unable to create to obtain configuration from"

bash tee 去除颜色

cakephp - CakeLog 不会在 Shell 中写入 debug.log

c# - 值在索引 1 处不同 - 对于相等的嵌套数组

c# - Maybe monad 如何充当短路?

c# - ASP.net 附件然后刷新页面