Что такое MDC (Mapped Diagnostic Context)?
MDC (Mapped Diagnostic Context) — механизм SLF4J/Logback для привязки контекстных данных к текущему потоку. Все лог-записи в рамках потока автоматически обогащаются данными из MDC.
Аналогия из жизни: MDC — это как бейдж посетителя в бизнес-центре. Пока бейдж надет, каждая камера на каждом этаже автоматически идентифицирует человека. Не нужно представляться у каждой двери.
Основное применение — correlation ID
Все лог-записи одного HTTP-запроса связываются единым идентификатором:
Фильтр для установки requestId в MDC
@Component
public class RequestFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
throws IOException, ServletException {
String requestId = ((HttpServletRequest) req).getHeader("X-Request-ID");
if (requestId == null) {
requestId = UUID.randomUUID().toString();
}
MDC.put("requestId", requestId);
try {
chain.doFilter(req, resp);
} finally {
MDC.clear(); // ОБЯЗАТЕЛЬНО очистить!
}
}
}
Конфигурация Logback для вывода MDC
Пример
<pattern>%d{ISO8601} [%thread] [%X{requestId}] %-5level %logger{36} - %msg%n</pattern>
<!-- %X{requestId} — подставляет значение из MDC -->
Результат в логах
Пример
2026-04-22 10:15:32.456 [http-nio-8080-exec-1] [a1b2c3d4] INFO OrderService - Создание заказа
2026-04-22 10:15:32.789 [http-nio-8080-exec-1] [a1b2c3d4] INFO PaymentService - Оплата обработана
2026-04-22 10:15:33.012 [http-nio-8080-exec-1] [a1b2c3d4] INFO NotificationService - Уведомление отправлено
Все три записи связаны одним requestId — можно отследить весь путь запроса через систему.
Как работает MDC внутри
MDC основан на ThreadLocal — каждый поток хранит свою копию контекстных данных. Это означает:
| Сценарий | Поведение MDC | Решение |
|---|---|---|
| Синхронный код | Работает автоматически | - |
@Async методы |
Новый поток не наследует MDC | TaskDecorator для копирования |
| Reactive (WebFlux) | ThreadLocal не работает |
Reactor Context |
| Virtual Threads | Работает, но при миллионах потоков расходует память | Рассмотрите ScopedValue |
Частые ошибки
- Забыть
MDC.clear()вfinally— утечка контекста между запросами в пуле потоков (thread reuse) - MDC в
@Asyncметодах — новый поток не наследует MDC; нужен TaskDecorator для копирования - MDC с Virtual Threads — при миллионах потоков MDC (на основе ThreadLocal) потребляет значительную память
Как используется в 2026
- MDC + correlation ID — стандартный паттерн для tracing в микросервисах
- Micrometer Tracing (Spring Boot 3.x) автоматически пробрасывает traceId/spanId в MDC
- В реактивном стеке (WebFlux) вместо MDC используется Reactor Context
На собеседовании: главное — объяснить связку MDC + ThreadLocal + обязательная очистка. Частая ошибка кандидатов — не упомянуть проблему с асинхронным кодом, где MDC не передаётся автоматически.