如何使用stringToMatch筛选器在log4net中将消息与换行符匹配?
我在配置a以匹配a时遇到问题 带有换行符的消息中的字符串。我想跳过一些消息,我 我们已经添加了一个这样的过滤器,它的工作如何使用stringToMatch筛选器在log4net中将消息与换行符匹配?,log4net,log4net-configuration,Log4net,Log4net Configuration,我在配置a以匹配a时遇到问题 带有换行符的消息中的字符串。我想跳过一些消息,我 我们已经添加了一个这样的过滤器,它的工作 但是如果我将stringToMatch更改为“现有连接已断开” “由远程主机强制关闭”,发生在 “过滤器不工作”消息。是因为中国的新线吗 还是我做错了什么 典型的消息可能如下所示: ------示例消息---------------------------- 2011-05-04 16:22:24,078 [Client (connected from "127.0.0.
但是如果我将stringToMatch
更改为“现有连接已断开”
“由远程主机强制关闭”,发生在
“过滤器不工作”消息。是因为中国的新线吗
还是我做错了什么
典型的消息可能如下所示:
------示例消息----------------------------
2011-05-04 16:22:24,078 [Client (connected from "127.0.0.1:4076" at 16:22)] ERROR - Unexpected exception in SocketThreadWorker System.Net.Sockets.SocketException:
An existing connection was forcibly closed by the remote host at System.Net.Sockets.Socket.EndReceive(IAsyncResult asyncResult)
------结束示例消息---------------------------
2011-05-04 16:22:24,078 [Client (connected from "127.0.0.1:4076" at 16:22)] ERROR - Unexpected exception in SocketThreadWorker System.Net.Sockets.SocketException:
An existing connection was forcibly closed by the remote host at System.Net.Sockets.Socket.EndReceive(IAsyncResult asyncResult)
“SocketThreadWorker中的意外异常”位于消息的第一行,而“现有连接被强制关闭”位于第二行
编辑
appender如下所示:
我不想通知任何人这个错误消息,因为它真的没有那么严重。消息不是由我自己的代码生成的,而是来自我使用的库。log4net附加说明
SocketThreadWorker
正在抛出一个错误。异常消息“现有连接被远程主机强制关闭”由映射
生成log语句的代码看起来像一个未处理的异常处理程序(通过打印的消息“意外异常…”)。但是,对于这个答案,想象一下它看起来是这样的
try
{
...
}
catch (Exception e)
{
_log.Error("Unexpected exception in SocketThreadWorker", e);
}
log4net在封面下生产的是一个。它包含提供的日志消息和异常对象(分别)。每个附加器都可以决定如何将这两个项写入其最终目的地(以及其他属性、布局参数等)
StringToMatch
过滤器仅对日志消息起作用。不在异常消息上!查看下面的代码,我们将构建一个系统和一个测试,帮助我们调试问题
繁殖与深潜
下面是一个简单的套接字异常抛出类
public class SocketThreadWorker
{
public void DoWork()
{
throw new SocketException(10054);
}
}
我们将log4net配置为使用带有字符串匹配筛选器的ConsoleAppender
,匹配异常消息字符串
public static class LocalLoggingConfiguration
{
public static void Configure()
{
var filter = new StringMatchFilter
{
StringToMatch = "An existing connection was forcibly closed by the remote host",
AcceptOnMatch = false,
};
var appender = new ConsoleAppender
{
Layout = new SimpleLayout()
};
appender.AddFilter(filter);
BasicConfigurator.Configure(appender);
}
}
我们配置log4net,获取一个记录器,并在测试中进行失败调用。您会注意到其他级别的一些日志语句和Error
中的另一个日志语句与我们的过滤器不匹配(如果它工作的话)。这样,我们可以确保不会意外丢失所有消息
[TestClass]
public class SocketLibraryTest
{
private readonly ILog _log = LogManager.GetLogger(typeof(SocketLibraryTest));
public SocketLibraryTest()
{
LocalLoggingConfiguration.Configure();
}
[TestMethod]
public void CatchThatPeskyException()
{
_log.Debug("Testing...");
try
{
new SocketThreadWorker().DoWork();
}
catch (Exception e)
{
_log.Info("An exception!");
_log.Error("Unexpected exception in SocketThreadWorker", e);
_log.Error("It wasn't that bad.");
}
}
}
在我的环境中,这个测试的输出在消息的另一行包含异常,因为默认情况下,appender将以这种方式打印异常对象
DEBUG - Testing...
INFO - An exception!
ERROR - Unexpected exception in SocketThreadWorker
System.Net.Sockets.SocketException (0x80004005): An existing connection was forcibly closed by the remote host
at SO5894291.SocketThreadWorker.DoWork() in d:\users\anthony.mastrean\documents\Projects\SO5894291\SO5894291\SocketLibraryTest.cs:line 16
at SO5894291.SocketLibraryTest.CatchThatPeskyException() in d:\users\anthony.mastrean\documents\Projects\SO5894291\SO5894291\SocketLibraryTest.cs:line 58
ERROR - It wasn't that bad.
如果修改appender筛选器以匹配不同消息的某个部分,您将看到它已正确配置并正常工作。将字符串更改为“Testing”,您将看到DEBUG
语句从控制台输出中消失
建议
您不希望在通用日志消息“意外异常…”上进行匹配。这样就有可能丢失信息。即使引入记录器匹配筛选器也不会有帮助,因为套接字工作人员可能会抛出其他异常(同样,可能会丢失消息)
我能想到的唯一选择是实现自己的例外消息omatchfilter
。我已经复制了StringToMatchFilter
的实现,将呈现的消息字符串替换为异常消息
public class ExceptionMessageToMatchFilter : StringMatchFilter
{
public override FilterDecision Decide(LoggingEvent loggingEvent)
{
if (loggingEvent == null)
throw new ArgumentNullException("loggingEvent");
if (loggingEvent.ExceptionObject == null)
return FilterDecision.Neutral;
var exceptionMessage = loggingEvent.GetExceptionString();
if (m_regexToMatch != null)
{
if (!m_regexToMatch.Match(exceptionMessage).Success)
return FilterDecision.Neutral;
return m_acceptOnMatch ? FilterDecision.Accept : FilterDecision.Deny;
}
if (m_stringToMatch == null || exceptionMessage.IndexOf(m_stringToMatch) == -1)
{
return FilterDecision.Neutral;
}
return m_acceptOnMatch ? FilterDecision.Accept : FilterDecision.Deny;
}
}
我会小心处理GetExceptionString()
调用,我不知道它是否可以返回null
。或者,如果没有消息,您想做什么(消息是否为空?您应该返回中性还是继续匹配?)
在log4net配置中装配起来非常容易(特别是因为它具有从字符串到匹配过滤器的所有属性)
您可以发布您的log4net配置部分吗?根据我的回答,拥有生成此log语句的代码可能会很好。此外,因为我认为问题是“无法解决”的,所以您可以发布您想要完成的任务(一般而言,而不是log4net),以便我们可以想出替代方案吗?Daniel,你能回来接受答案吗?正如你从我添加的附件中看到的,这只是一条信息,而不是例外。我无法访问生成log语句的代码。还有什么想法吗?对否决票发表评论会有帮助的。你怎么能否决我用代码验证过的答案?非常有用的答案!刚刚实现了你的logger类,因为我必须对异常进行过滤。只是想纠正一些事情。在配置新过滤器的最后一位,XML节点应该是“过滤器”而不是“附加器”。此外,程序集应该只是“MyAssembly”,而不是“MyAssembly.dll”。
<filter type="MyNamespace.ExceptionMessageToMatchFilter, MyAssembly">
<stringToMatch value="An existing connection was forcibly closed by the remote host" />
<acceptOnMatch value="false" />
</filter>