是否有可能从特定线程中过滤掉日志条目?
我使用 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.
确保过滤器顺序如下:
- 过滤您不想要的线程
- 如果匹配,则拒绝消息并且不传递给下一个过滤器(由于
<acceptOnMatch value="false" />
- 如果不匹配,则将消息传递给链中的下一个过滤器
- 如果匹配,则拒绝消息并且不传递给下一个过滤器(由于
- 记录器过滤器
- 如果匹配,消息被接受并且不传递给下一个过滤器
- 如果不匹配,则将消息传递给链中的下一个过滤器
- 全部拒绝
- 消息被拒绝
- 过滤您不想要的线程
完整示例:
<?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/