How do I configure Logback to ignore logging on exceptions of a particular type?
This is an additional example of the response of @palacsint that apply when the error is not an exception using JaninoEventEvaluator:
<filter class="ch.qos.logback.core.filter.EvaluatorFilter">
<evaluator>
<expression>logger.equals("org.docx4j.fonts.GlyphCheck") && level == ERROR</expression>
</evaluator>
<onMatch>DENY</onMatch>
</filter>
You can do it with a simple EvaluatorFilter
:
<filter class="ch.qos.logback.core.filter.EvaluatorFilter">
<evaluator>
<expression>java.lang.RuntimeException.class.isInstance(throwable)</expression>
</evaluator>
<onMatch>DENY</onMatch>
</filter>
Please note that you need the following dependency in your pom.xml
as well:
<dependency>
<groupId>org.codehaus.janino</groupId>
<artifactId>janino</artifactId>
<version>2.5.16</version>
</dependency>
Another possible solution is a custom Filter
implementation:
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.classic.spi.IThrowableProxy;
import ch.qos.logback.classic.spi.ThrowableProxy;
import ch.qos.logback.core.filter.Filter;
import ch.qos.logback.core.spi.FilterReply;
public class SampleFilter extends Filter<ILoggingEvent> {
private Class<?> exceptionClass;
public SampleFilter() {
}
@Override
public FilterReply decide(final ILoggingEvent event) {
final IThrowableProxy throwableProxy = event.getThrowableProxy();
if (throwableProxy == null) {
return FilterReply.NEUTRAL;
}
if (!(throwableProxy instanceof ThrowableProxy)) {
return FilterReply.NEUTRAL;
}
final ThrowableProxy throwableProxyImpl =
(ThrowableProxy) throwableProxy;
final Throwable throwable = throwableProxyImpl.getThrowable();
if (exceptionClass.isInstance(throwable)) {
return FilterReply.DENY;
}
return FilterReply.NEUTRAL;
}
public void setExceptionClassName(final String exceptionClassName) {
try {
exceptionClass = Class.forName(exceptionClassName);
} catch (final ClassNotFoundException e) {
throw new IllegalArgumentException("Class is unavailable: "
+ exceptionClassName, e);
}
}
}
With a proper config:
<filter class="hu.palacsint.logbacktest.SampleFilter">
<exceptionClassName>java.lang.Exception</exceptionClassName>
</filter>
In a TurboFilter
you get the thrown Throwable instance directly, so you can call the isInstance method without manually casting the IThrowableProxy
to ThrowableProxy
.
Further documentation
This question is 5 years old, but I'm supplying the solution I found just to keep it up to date.
I found a solution in the offical docs: http://logback.qos.ch/manual/layouts.html
For my particular situation, which is a 17 year old web site running plain old servlets (ah, the days), the servlet is now throwing an exception if the user was not logged in. So here's my code snippets:
Servlet
try {
InvalidLoginException.throwIfBadLogin(webUser);
// main logic here
} catch (InvalidLoginException e) {
throw e;
} catch (Throwable t) {
log.error(t);
throw new UnhandledException(t);
}
web.xml
<error-page>
<exception-type>com.mycompany.servlet.exception.InvalidLoginException</exception-type>
<location>/servlet/Login</location>
</error-page>
From the setup above, I didn't want to log this exception as it's not really an exception, but rather a break in logic to redirect to login.
So, the start of my logback.xml file is this:
<configuration packagingData="true" scan="true" debug="true" scanPeriod="30 seconds">
<evaluator name="InvalidLoginExceptionSuppressor">
<expression>throwable != null && throwable instanceof com.mycompany.servlet.exception.InvalidLoginException</expression>
</evaluator>
and further down in the logback.xml file, my appenders:
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{MM-dd HH:mm:ss.SSS} %-5level %logger{36} - %msg %ex{full,InvalidLoginExceptionSuppressor}%n</pattern>
<immediateFlush>false</immediateFlush>
</encoder>
Also note, in order to this work, I had to include janino to handle the expression parsing.