Как добавить уникальный идентификатор запроса (traceId) в логи приложения?

«Как добавить уникальный идентификатор запроса (traceId) в логи приложения?» — вопрос из категории DevOps, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

traceId (идентификатор сквозной трассировки) позволяет связать все логи, относящиеся к одному запросу, даже в распределенной системе. Основные подходы:

1. Использование MDC (Mapped Diagnostic Context) вручную:

  • MDC — это потокобезопасное хранилище контекста, привязанное к потоку выполнения.
  • Шаг 1: Установить traceId (например, в Servlet Filter) и поместить его в MDC.
    @Component
    public class TraceIdFilter implements Filter {
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        String traceId = UUID.randomUUID().toString();
        MDC.put("traceId", traceId); // Помещаем в контекст
        try {
            chain.doFilter(req, res);
        } finally {
            MDC.clear(); // Очищаем после завершения запроса
        }
    }
    }
  • Шаг 2: Настроить шаблон логов (например, в logback-spring.xml) для включения traceId.
    <configuration>
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <!-- Ключевая часть: %X{traceId} извлекает значение из MDC -->
            <pattern>%d{ISO8601} [%thread] %-5level %logger{36} [traceId=%X{traceId}] - %msg%n</pattern>
        </encoder>
    </appender>
    <root level="INFO">
        <appender-ref ref="CONSOLE" />
    </root>
    </configuration>

2. Использование Spring Cloud Sleuth / Micrometer Tracing (рекомендуется):

  • Автоматически генерирует traceId и spanId, интегрируется с логгированием и внешними системами (Zipkin, Jaeger).
  • Зависимость (Spring Boot 3+):
    <dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-tracing-bridge-brave</artifactId>
    </dependency>
  • Sleuth автоматически добавляет [app-name,traceId,spanId,exportable] в шаблон логов Slf4J. В логах будет видно: 2023-... INFO [my-app, 76bdf78e7f7e5c92, 76bdf78e7f7e5c92] ...

Ключевой принцип: traceId должен быть уникальным для каждого входящего запроса и передаваться во все вложенные вызовы (другие методы, HTTP-запросы к другим сервисам, сообщения в брокер).