我正在使用slf4j
来在控制台和自定义文件中记录自定义异常及其堆栈跟踪。我遇到了一种情况,我必须截断一些非关键异常的堆栈跟踪。
使用this documentation,在我的logback.xml
文件中添加了以下配置
<evaluator name="DISPLAY_EX_EVAL">
<expression>throwable != null && throwable instanceof com.abc.NonCriticalException</expression>
</evaluator>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%-30(%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread]) %-5level
%logger{150} -%msg%n%ex{full, DISPLAY_EX_EVAL}
</pattern>
</encoder>
</appender>
但是,上述配置在记录配置的异常期间会删除所有堆栈跟踪。有没有办法记录匹配异常的截断的堆栈跟踪(1或2行)?
答案 0 :(得分:0)
但是为什么要完全截断堆栈跟踪?为什么不记录完整的堆栈跟踪。毕竟,它是重要且有用的信息。对吧?
我猜您在想必须log the stacktrace for all exceptions。那是一个错误。您只应记录堆栈跟踪以查找在被调用代码中指示 bug 的异常(意外异常)。当然,程序记录这些堆栈跟踪并不罕见,并且当它记录时,您将希望 full 堆栈跟踪可以帮助您调试问题。
答案 1 :(得分:0)
有一个开源库(由我编写),提供了智能的堆栈跟踪过滤。我在自己的项目中使用它,效果很好。以下是有关库的文章:Open-Source Java Library With Stack Trace Filtering, Silent String Parsing, and Version Comparison。专门查看“ 堆栈跟踪噪声滤波器”部分。基本上,它根据您设置的感兴趣的软件包前缀来过滤堆栈跟踪。您可以在Maven artifact或Github上找到该库(包括源代码和javadoc)。这是Javadoc。这是一个例子。假设您的代码位于软件包“ com.plain.*
”中。因此,如果将前缀设置为“ com.plain.
”,而不是原始堆栈跟踪:
at com.plain.BookService.listBooks()
at com.plain.BookService$FastClassByCGLIB$e7645040.invoke()
at net.sf.cglib.proxy.MethodProxy.invoke()
at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint()
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed()
at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed()
at com.plain.LoggingAspect.logging()
at sun.reflect.NativeMethodAccessorImpl.invoke0()
at sun.reflect.NativeMethodAccessorImpl.invoke()
at sun.reflect.DelegatingMethodAccessorImpl.invoke()
at java.lang.reflect.Method.invoke()
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs()
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod()
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke()
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed()
at org.springframework.aop.interceptor.AbstractTraceInterceptor.invoke()
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed()
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke()
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed()
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke()
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed()
at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept()
at com.plain.BookService$EnhancerByCGLIB$7cb147e4.listBooks()
at com.plain.web.BookController.listBooks()
将替换为:
at com.plain.BookService.listBooks()
at com.plain.BookService$FastClassByCGLIB$e7645040.invoke()
at net.sf.cglib.proxy.MethodProxy.invoke()
...
at com.plain.LoggingAspect.logging()
at sun.reflect.NativeMethodAccessorImpl.invoke0()
...
at com.plain.BookService$EnhancerByCGLIB$7cb147e4.listBooks()
at com.plain.web.BookController.listBooks()
该实用程序可以很好地与包括“由...引起”和“被抑制”的部分在内的整个stacktrace配合使用,并且可以即时(来自异常本身)或包含原始stacktrace的字符串进行过滤