Как создать эффективную систему логирования с использованием Aspect и Spring Cloud Sleuth



Книга <strong>Как создать эффективную систему логирования с использованием Aspect и Spring Cloud Sleuth</strong>

Надлежащая практика ведения логов  —  один из наиболее важных аспектов разработки программного обеспечения. Она помогает быстро понять контекст и локализовать проблему при отладке.



Skillfactory.ru

Самой большой сложностью может стать отсутствие у команды единой системы логирования. Если каждый придерживается того стиля ведения логов, который считает правильным, то человеку, занимающемуся дебаггингом, будет сложно каждый раз анализировать логи по-новому.


С другой стороны, если бы, создавая программу, можно было добавить определенный фреймворк логирования, который отлавливал бы наиболее важные для отладки кода аспекты, то для ошибок, связанных с “человеческим фактором”, осталось бы меньше места. 


В этой статье мы попытаемся найти решения для трех следующих задач.



  1. Отслеживание каждого вызова API по уникальному ID. Это поможет отследить все шаги в едином потоке кода.

  2. Отслеживание любых асинхронных вызовов по уникальному ID вызывающей стороны. Это оказывается затруднительным без передачи уникального ID в качестве параметра метода и логирования его в явном виде. Такое может привести к появлению ручных ошибок.

  3. Логирование API-запросов. Оно необходимо, чтобы определить путь исследуемого API и верифицировать каждый вызов с использованием тела и параметров запроса.


Что такое Spring Cloud Sleuth?


Spring Cloud Sleuth позволяет выполнять распределенную трассировку. Он предоставляет два ID для каждого из логов.


ID трассировки  —  уникальный ID, который отслеживает один запрос. Например, вызову GET API будет присвоен один ID трассировки, который можно задействовать для прослеживания маршрута этого API-вызова от запроса к ответу.


ID диапазона же будет присваиваться каждому уникальному шагу в трассировке при условии, что в одном запросе выполняется n уникальных задач. Об этом на примере  —  далее в статье.


Чтобы подключить Sleuth в проект Spring Boot, нужно добавить в pom-файл следующую зависимость:


<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>

Aspect и Pointcut




Поскольку аспектно-ориентированное программирование уже достаточно известно, мы не станем глубоко погружаться в его особенности.



Аспектно-ориентированное программирование используется для решения общих сквозных проблем. В нашем случае это  —  ведение логов.


Начнем с разработки класса Aspect, который определял бы Pointcut (совокупность точек соединения). Pointcut объявляет условие, соответствующее точке соединения. Точка соединения  —  это определенный шаг выполнения. В нашем случае Pointcut объявляет соответствующую точку как все методы в классе SampleResource.


Мы также объявляем Advice  —  @Before, который применяется перед выполнением метода, объявленного в Pointcut.


Чтобы включить аспектно-ориентированное программирование в SpringBoot, нужно добавить аннотацию к классу Main  —  @EnableAspectJAutoProxy.


В приложении мы логируем метод запроса, путь и параметры пути.


logger.info("Received call :: {} - {} - request param [{}]",request.getMethod(),request.getServletPath(),request.getParameter("name"));

Тестирование приложения


Воспользуемся нижеприведенным Curl для тестирования приложения: 


curl --location --request GET 'http://localhost:8090/api/greetings?name=James%20Bond'

Чтобы убедиться, что каждому запросу присваивается новый ID, мы дважды обратимся к упомянутому API.


Обратите внимание: мы также добавили в приложении асинхронный вызов, который сейчас просто печатает сообщение. Cледует ожидать (в идеале), что этому асинхронному вызову также будет присвоен уникальный ID диапазона.


public String sampleAsyncCall(String name) {
CompletableFuture.runAsync(() -> {
logger.info("Inside Async Call");
}, new TraceableExecutorService(beanFactory,executor));
return "Hello " + name;
}

Также обратите внимание, что для включения трассировки следует выполнять асинхронный вызов TraceableExecutorService. Если вместо этого использовать ScheduledExecutorService, ID диапазона и ID трассировки вернутся как null.


Проверим сгенерированные после двойного запроса к GET API логи.



При первом обращении к API запросу присваивается уникальный ID трассировки и ID диапазона. Когда из метода выполняется асинхронный вызов, он также получает уникальный ID диапазона.


При обращении к API во второй раз запросу присваивается новый ID трассировки и ID диапазона, а асинхронному вызову снова присваивается следующий ID диапазона.


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


С помощью Spring Sleuth мы избежали задачи по ручному присвоению уникальных ID каждому запросу, а затем асинхронным вызовам.


Заключение


Мы рассмотрели, как эффективно пользоваться Aspect и Spring Cloud Sleuth для создания эффективной системы ведения логов, которая почти исключает риск человеческих ошибок.


Весь код из статьи доступен на Github.



434   0  
    Ничего не найдено.

Добавить ответ:
Отменить.