Статьи

Фильтровать нерелевантные линии трассировки стека в журналах

Я люблю следы стека. Не потому, что я люблю ошибки, а в тот момент, когда они возникают, трассировка стека является бесценным источником информации. Например, в веб-приложении трассировка стека показывает полный путь обработки запроса, от сокета HTTP, через фильтры, сервлеты, контроллеры, службы, DAO и т. Д. — до места, где произошла ошибка. Вы можете прочитать их как хорошую книгу, где каждое событие имеет причину и следствие. Я даже реализовал некоторые усовершенствования в том, как Logback печатает исключения, сначала посмотрите причину регистрации исключений .

Но одна вещь беспокоит меня некоторое время. Печально известный признак « след из стека » — следы из стека, содержащие сотни нерелевантных, загадочных, часто автоматически генерируемых методов. Фреймворки AOP и чрезмерно спроектированные библиотеки имеют тенденцию производить безумно длинные трассы выполнения. Позвольте мне показать пример из жизни. В примере приложения я использую следующий стек технологий:

Цвета важны. В соответствии с цветом фреймворка / слоя я нарисовал образец стека трассировки, вызванный исключением, которое выдается где-то глубоко при попытке извлечь данные из базы данных:

Уже не так приятно, тебе не кажется? Размещение Spring между приложением и Hibernate на первой диаграмме было огромным упрощением. Spring Framework — это связующий код, который связывает и перехватывает вашу бизнес-логику с окружающими слоями. Вот почему код приложения разбросан и чередуется десятками строк технических вызовов (см. Зеленые линии). Я вложил в приложение как можно больше материала (Spring AOP, аннотации на уровне метода @Secured, настраиваемые аспекты и перехватчики и т. Д.), Чтобы подчеркнуть проблему, но это не зависит от Spring. Серверы EJB генерируют одинаково ужасные следы стека (… из ада) между вызовами EJB. Должен ли я заботиться? Подумайте об этом, когда вы невинно вызываете BookService.listBooks() из BookController.listBooks() ожидаете ли вы увидеть это?

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
at com.blogspot.nurkiewicz.BookService.listBooks()
at com.blogspot.nurkiewicz.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.blogspot.nurkiewicz.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.blogspot.nurkiewicz.BookService$$EnhancerByCGLIB$$7cb147e4.listBooks()
at com.blogspot.nurkiewicz.web.BookController.listBooks()

А вы когда-нибудь замечали, что между ними есть особенность? В том-то и дело, что в трассировке стека сейчас так много шума, что следовать реальной бизнес-логике практически невозможно. Один из лучших инструментов для устранения неполадок, который у нас есть, состоит из ненужных вещей, связанных с фреймворком, которые нам не нужны в 99% случаев.

Инструменты и IDE делают хорошую работу по снижению шума. Eclipse имеет шаблоны фильтров трассировки стека для Junit , IntelliJ IDEA поддерживает настройку свертывания консоли . См. Также: Удаление шума из следов стека Java , что вдохновило меня на написание этой статьи. Так почему бы не иметь такую ​​возможность в самом корне — в каркасе журналирования, таком как Logback?

Я реализовал очень простое улучшение в Logback. По сути, вы можете определить набор шаблонов фреймов трассировки стека, которые предполагается исключить из трасс стека. Как правило, вы будете использовать имена пакетов или классов, которые вас не интересуют. Это пример logback.xml с включенной новой функцией:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
<root level="ALL">
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>%d{HH:mm:ss.SSS} | %-5level | %thread | %logger{1} | %m%n%rEx{full,
          java.lang.reflect.Method,
          org.apache.catalina,
          org.springframework.aop,
          org.springframework.security,
          org.springframework.transaction,
          org.springframework.web,
          sun.reflect,
          net.sf.cglib,
          ByCGLIB
        }
        </pattern>
    </encoder>
  </appender>
</root>

Я немного экстремален в фильтрации почти всей среды Spring + отражения Java и классов CGLIB. Но это просто, чтобы дать вам представление, сколько вы можете получить. Та же самая ошибка после применения моего улучшения к Logback:

Напоминаем, зеленый — это наше приложение. Наконец, в одном месте, наконец, вы действительно можете увидеть, что делал ваш код, когда произошла ошибка:

  в com.blogspot.nurkiewicz.DefaultBookHelper.findBooks ()
 в com.blogspot.nurkiewicz.BookService.listBooks ()
 в com.blogspot.nurkiewicz.LoggingAspect.logging ()
 на com.blogspot.nurkiewicz.web.BookController.listBooks ()

Simpler? Если вам нравится эта функция, я открыл тикет LBCLASSIC-325 : фильтрация выбранных кадров трассировки стека . Голосуй и обсуждай. Это только подтверждение концепции, но если вы хотите взглянуть на реализацию (улучшения приветствуются!), Она доступна в моей ветке Logback (около 20 строк кода).

Ссылка: Фильтрация нерелевантных линий трассировки стека в журналах от нашего партнера JCG