如何不在 Logback 中记录特定类型的异常?
Posted
技术标签:
【中文标题】如何不在 Logback 中记录特定类型的异常?【英文标题】:How do I not log a particular type of Exception in Logback? 【发布时间】:2011-09-02 21:20:46 【问题描述】:如何配置 Logback 以忽略特定类型异常的日志记录?
【问题讨论】:
【参考方案1】:你可以用一个简单的EvaluatorFilter
:
<filter class="ch.qos.logback.core.filter.EvaluatorFilter">
<evaluator>
<expression>java.lang.RuntimeException.class.isInstance(throwable)</expression>
</evaluator>
<onMatch>DENY</onMatch>
</filter>
请注意,您的pom.xml
中还需要以下依赖项:
<dependency>
<groupId>org.codehaus.janino</groupId>
<artifactId>janino</artifactId>
<version>2.5.16</version>
</dependency>
另一种可能的解决方案是自定义Filter
实现:
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);
使用适当的配置:
<filter class="hu.palacsint.logbacktest.SampleFilter">
<exceptionClassName>java.lang.Exception</exceptionClassName>
</filter>
在TurboFilter
you get the thrown Throwable
instance directly 中,因此您可以调用isInstance
方法,而无需手动将IThrowableProxy
强制转换为ThrowableProxy
。
Further documentation
【讨论】:
谢谢,我已经解决了这个特定问题,但这是未来的好信息。【参考方案2】:这个问题已有 5 年历史了,但我提供的解决方案只是为了使其保持最新状态。
我在官方文档中找到了解决方案: http://logback.qos.ch/manual/layouts.html
对于我的特殊情况,这是一个运行普通旧 servlet 的 17 年网站(啊,那些日子),如果用户没有登录,servlet 现在会抛出异常。所以这是我的代码 sn-ps:
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>
根据上面的设置,我不想记录此异常,因为它真的不是异常,而是重定向到登录的逻辑中断。
所以,我的 logback.xml 文件的开头是这样的:
<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>
在 logback.xml 文件的更下方,我的附加程序:
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%dMM-dd HH:mm:ss.SSS %-5level %logger36 - %msg %exfull,InvalidLoginExceptionSuppressor%n</pattern>
<immediateFlush>false</immediateFlush>
</encoder>
另外请注意,为了完成这项工作,我必须包含 janino 来处理表达式解析。
【讨论】:
【参考方案3】:这是@palacsint 响应的另一个示例,当错误不是异常时使用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>
【讨论】:
如果它是您忽略的记录器,您可以禁用该记录器以上是关于如何不在 Logback 中记录特定类型的异常?的主要内容,如果未能解决你的问题,请参考以下文章
logback 不会将异常记录到从 ThreadPoolTaskExecutor 池线程抛出的文件中