5

I'm using slf4j to log custom exceptions and their stack traces in both console and a custom file. I met a situation that I had to truncate the stack traces of some non-critical exceptions.

Using this documentation, I added the following configuration in my logback.xml file

<evaluator name="DISPLAY_EX_EVAL">
    <expression>throwable != null &amp;&amp; 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>

But, the above configuration removes all the stacktraces during logging of the configured exception. Is there a way to log the truncated stack trace (1 or 2 lines) of the matched exception ?

Abhishek Ramachandran
  • 1,160
  • 1
  • 13
  • 34
  • Hello @Abhishek. Is this still an issue for you? Lemme see if I understood your question: On the console you want the stack trace messages to be truncated, but you still would want them to be logged fully to a file. Is that correct? – Gabriel Robaina Jun 29 '19 at 15:44
  • Please take a look at my other answer about logging. https://stackoverflow.com/questions/56795320/is-there-a-friendlier-view-of-beancreationexception-applicationcontext-load-pr maybe it helps you in any way. I did not really understand your question tho... – Gabriel Robaina Jul 01 '19 at 22:59

2 Answers2

3

There is an open-source library (written by me) that provides smart stacktrace filtering. I use it in my own projects and it works great. Here is the article about the library: Open-Source Java Library With Stack Trace Filtering, Silent String Parsing, and Version Comparison. Look specifically for paragraph "Stack Trace Noise Filter". Basically it filters the stacktrace based on a package prefix that you set that interests you. You can find the library as Maven artifact or on the Github (including source code and javadoc). Here is Javadoc. Here is an example. Assume that your code is located in package "com.plain.*". So if you set your prefix to "com.plain." than the original stacktrace:

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()

will be replaced with:

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()

The utility works well with entire stacktrace including "caused by" and "suppressed" parts, as well as filtering could be done on the fly (from exception itself) or from string that contains the original stacktrace

Michael Gantman
  • 7,315
  • 2
  • 19
  • 36
0

But why do you want to truncate the stacktrace at all? Why not log the full stacktrace. After all, it's important and useful information. Right?

I guess you are thinking you must log the stacktrace for all exceptions. That is a mistake. You should log a stack trace only for exceptions that indicate a bug in called code (an unexpected exception). Of course, it should be uncommon that your program logs those stack traces, and when it does, you will want the full stack trace to help you debug the problem.

Raedwald
  • 46,613
  • 43
  • 151
  • 237