«1. Обзор

В этой статье мы рассмотрим Spring Cloud Sleuth и посмотрим, как мы можем использовать его для трассировки в Spring Boot. Он добавляет полезную дополнительную информацию в наши журналы и упрощает отладку действий, добавляя к ним уникальные идентификаторы. Эти действия называются следами в терминологии Sleuth. Они могут состоять из нескольких ступеней, называемых пролетами.

Например, трассировкой может быть запрос GET, запрашивающий данные из нашего приложения. Когда наше приложение обрабатывает запрос, его можно разделить на более мелкие этапы: авторизация пользователя, выполнение запроса к базе данных, преобразование ответа. Каждый из этих шагов является уникальным отрезком, принадлежащим одной и той же трассе.

В некоторых случаях нам может понадобиться получить идентификатор текущей трассы или диапазона. Например, мы могли бы отправить их команде разработчиков при возникновении инцидента. Затем они могут использовать это для отладки и устранения проблемы.

2. Настройка приложения

Давайте начнем с создания проекта Spring Boot и добавления зависимости spring-cloud-starter-sleuth:

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

Эта начальная зависимость хорошо интегрируется с Spring Boot и обеспечивает необходимая конфигурация, чтобы начать использовать Spring Cloud Sleuth.

Однако мы можем сделать еще один шаг. Давайте установим имя нашего приложения в файле application.properties, таким образом, мы увидим это в журналах вместе с идентификаторами трассировки и интервала:

spring.application.name=Baeldung Sleuth Tutorial

Теперь нам нужна точка входа в наше приложение. . Давайте создадим контроллер REST с одной конечной точкой GET:

@RestController
public class SleuthTraceIdController {

    @GetMapping("/traceid")
    public String getSleuthTraceId() {
        return "Hello from Sleuth";
    }
}

Давайте посетим нашу конечную точку API по адресу http://localhost:8080/traceid. В ответе мы должны увидеть «Hello from Sleuth».

3. Ведение журнала

Давайте добавим оператор журнала в метод getSleuthTraceId. Во-первых, нам нужен Logger для нашего класса. Затем мы можем записать сообщение:

private static final Logger logger = LoggerFactory.getLogger(SleuthTraceIdController.class);

@GetMapping("/traceid")
public String getSleuthTraceId() {
    logger.info("Hello with Sleuth");
    return "Hello from Sleuth";
}

Давайте еще раз вызовем нашу конечную точку API и проверим журналы. Мы должны найти что-то похожее на это:

INFO [Baeldung Sleuth Tutorial,e48f140a63bb9fbb,e48f140a63bb9fbb] 9208 --- [nio-8080-exec-1] c.b.s.traceid.SleuthTraceIdController : Hello with Sleuth

Обратите внимание, что имя приложения находится в скобках в начале. Эти скобки добавлены Sleuth. Они представляют имя приложения, идентификатор трассировки и идентификатор диапазона.

4. Текущая трассировка и диапазон

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

В нашей реализации мы упростим этот вариант использования и просто будем записывать идентификаторы трассировки в консоль.

Во-первых, нам нужно получить экземпляр объекта Tracer. Давайте внедрим его в наш контроллер и получим текущий диапазон:

@Autowired
private Tracer tracer;

@GetMapping("/traceid")
public String getSleuthTraceId() {
    logger.info("Hello with Sleuth");
    Span span = tracer.currentSpan();
    return "Hello from Sleuth";
}

Обратите внимание, что метод currentSpan может возвращать значение null, если в данный момент активного диапазона нет. Поэтому мы должны выполнить дополнительную проверку, чтобы увидеть, можем ли мы продолжить и использовать этот объект Span, не получая исключение NullPointerException. Давайте выполним эту проверку и зарегистрируем текущие идентификаторы трассировки и интервала:

Span span = tracer.currentSpan();
if (span != null) {
    logger.info("Trace ID {}", span.context().traceIdString());
    logger.info("Span ID {}", span.context().spanIdString());
}

Давайте запустим приложение и будем искать эти сообщения при посещении нашей конечной точки API. Они должны содержать те же идентификаторы, что и скобки, добавленные Sleuth.

5. Идентификатор трассы и участка в виде десятичных чисел

Существует еще один способ получить идентификатор участка с помощью метода spanId вместо spanIdString. Разница между ними в том, что последний возвращает шестнадцатеричное представление значения, а первый возвращает десятичное число. Давайте сравним их в действии и также запишем десятичное значение:

Span span = tracer.currentSpan();
if (span != null) {
    logger.info("Span ID hex {}", span.context().spanIdString());
    logger.info("Span ID decimal {}", span.context().spanId());
}

Два значения представляют одно и то же число, и вывод должен выглядеть примерно так:

INFO [Baeldung Sleuth Tutorial,0de46b6fcbc8da83,0de46b6fcbc8da83] 8648 --- [nio-8080-exec-3] c.b.s.traceid.SleuthTraceIdController    : Span ID hex 0de46b6fcbc8da83
INFO [Baeldung Sleuth Tutorial,0de46b6fcbc8da83,0de46b6fcbc8da83] 8648 --- [nio-8080-exec-3] c.b.s.traceid.SleuthTraceIdController    : Span ID decimal 1001043145087572611

Аналогично, это относится к также идентификаторы трассировки. Вместо traceIdString мы можем использовать метод traceId. traceIdString возвращает шестнадцатеричное значение, а traceId возвращает десятичное значение:

logger.info("Trace ID hex {}", span.context().traceIdString());
logger.info("Trace ID decimal {}", span.context().traceId());

Вывод очень похож на предыдущий. Он содержит идентификатор трассы сначала в шестнадцатеричном, а затем в десятичном формате:

INFO [Baeldung Sleuth Tutorial,34ec0b8ac9d65e91,34ec0b8ac9d65e91] 7384 --- [nio-8080-exec-1] c.b.s.traceid.SleuthTraceIdController    : Trace ID hex 34ec0b8ac9d65e91
INFO [Baeldung Sleuth Tutorial,34ec0b8ac9d65e91,34ec0b8ac9d65e91] 7384 --- [nio-8080-exec-1] c.b.s.traceid.SleuthTraceIdController    : Trace ID decimal 3813435675195629201

6. Заключение

«В этой статье мы обсудили, как Spring Cloud Sleuth может помочь в отладке и отслеживании событий в Spring Boot. Во-первых, мы использовали объект Tracer для ссылки на текущий диапазон и TraceContext. После этого мы смогли получить идентификатор текущей трассы и диапазона. Кроме того, мы увидели, как разные методы возвращают ID в разных системах счисления.

Как всегда, исходный код с этими примерами доступен на GitHub.