Reputation: 1322
How can I filter logging based on a logged exception's message?
Code looks like this:
try {
someService.DoSomeWorkflow();
} catch(Exception e) {
log.Error("Hey I have an error", e);
}
Config looks like this:
<appender name="EventLogger" type="log4net.Appender.EventLogAppender">
<applicationName value="foo" />
<layout type="log4net.Layout.PatternLayout" value="PID:%P{pid}: %message" />
<filter type="log4net.Filter.StringMatchFilter">
<stringToMatch value="TextInsideTheException" />
</filter>
</appender>
I'm finding that I can filter only on the logged message ("Hey I have an error") but it seemingly ignores the exception's message. Since this is in our production environment I can't make any code changes so I can't change the logged message. Is there some configuration that would specify to also check the exception's message?
Upvotes: 3
Views: 2222
Reputation: 301
Here are basic implementations based on Peter's accepted answer
using System;
using log4net.Core;
namespace log4net.Filter
{
public abstract class ExceptionFilterBase : FilterSkeleton
{
public override FilterDecision Decide(LoggingEvent loggingEvent)
{
if (loggingEvent == null)
throw new ArgumentNullException("loggingEvent");
var str = GetString(loggingEvent);
if (StringToMatch == null || string.IsNullOrEmpty(str) || !str.Contains(StringToMatch))
return FilterDecision.Neutral;
return AcceptOnMatch ? FilterDecision.Accept : FilterDecision.Deny;
}
protected abstract string GetString(LoggingEvent loggingEvent);
public string StringToMatch { get; set; }
public bool AcceptOnMatch { get; set; }
}
public class ExceptionMessageFilter : ExceptionFilterBase
{
protected override string GetString(LoggingEvent loggingEvent)
{
return loggingEvent.ExceptionObject == null
? null : loggingEvent.ExceptionObject.Message;
}
}
public class ExceptionTypeFilter : ExceptionFilterBase
{
protected override string GetString(LoggingEvent loggingEvent)
{
return loggingEvent.ExceptionObject == null
? null : loggingEvent.ExceptionObject.GetType().FullName;
}
}
public class ExceptionStackFilter : ExceptionFilterBase
{
protected override string GetString(LoggingEvent loggingEvent)
{
return loggingEvent.ExceptionObject == null
? null : loggingEvent.ExceptionObject.StackTrace;
}
}
}
Configuration file
<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="Client.log" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date{yyyy/MM/dd HH:mm:ss,fff} [%-5level] %logger - %message%newline" />
</layout>
<filter type="log4net.Filter.StringMatchFilter">
<stringToMatch value="Token is not valid." />
<acceptOnMatch value="false" />
</filter>
<filter type="log4net.Filter.ExceptionMessageFilter, YourAssembly">
<stringToMatch value="Application is not installed." />
<acceptOnMatch value="false" />
</filter>
<filter type="log4net.Filter.ExceptionTypeFilter, YourAssembly">
<stringToMatch value="System.Deployment.Application.DeploymentException" />
<acceptOnMatch value="false" />
</filter>
<filter type="log4net.Filter.ExceptionStackFilter, YourAssembly">
<stringToMatch value="at System.Deployment.Application.ComponentStore.GetPropertyString(DefinitionAppId appId, String propName)" />
<acceptOnMatch value="false" />
</filter>
</appender>
Upvotes: 1
Reputation: 33910
By subclassing FilterSkeleton, you can implement a filter that evaluates the exception text. Or exception type for that matter.
Upvotes: 2
Reputation: 3428
Try this:
log.Error("Hey I have an error: " + e.Message);
Edit: Sorry, didn't see that you cannot change that line...
Upvotes: -2