Знакомая ситуация: микросервис начинает тормозить, логи чистые, CPU в норме, а команда две недели перебирает гипотезы. Оказывается один сервис молча ретраит внешний API без таймаута. С нормальным трейсингом нашли бы за час. Вот как это настроить.
🔵 Что изменилось в Spring Boot 3
Главное: Spring Cloud Sleuth мёртв. Вместо него — Micrometer Tracing. Настройки другие, зависимости другие, подводные камни другие.
7 шагов от нуля до дашборда
1️⃣ Зависимости
spring-boot-starter-actuator
micrometer-registry-prometheus
micrometer-tracing-bridge-brave
zipkin-reporter-brave
Actuator даёт эндпоинты, micrometer — экспорт метрик в Prometheus, brave + zipkin — отправку трейсов.
2️⃣ Открываем /prometheus
В application.yml включаем экспорт метрик:
management:
endpoints:
web:
exposure:
include: health,info,prometheus
metrics:
export:
prometheus:
enabled: true
tags:
application: my-awesome-service
Тег application — это метка, по которой потом в Prometheus и Grafana можно фильтровать метрики конкретного сервиса. Когда у вас 10+ микросервисов без этого каша.
Проверка: открываем http://localhost:8080/actuator/prometheus, если видим простыню из jvm_memory_used_bytes, http_server_requests_seconds и прочих метрик, работает.
3️⃣ Настраиваем трейсинг
management:
tracing:
sampling:
probability: 1.0 # для теста, в проде 0.1
zipkin:
tracing:
endpoint: http://localhost:9411/api/v2/spans
Обратите внимание: endpoint теперь /api/v2/spans, а не старый формат.
4️⃣ Прокидываем traceId в логи
Подводный камень: Micrometer Tracing может не прокидывать traceId в MDC автоматически. Решение — явные бины Slf4JEventListener и BraveBaggageTagCorrelation в @Configuration классе. Если используете OTel bridge вместо Brave — нужен OtelBaggageTagCorrelation.
5️⃣ Prometheus
Создаём prometheus.yml с targets: ['app:8080'] и поднимаем через Docker Compose в одной сети с приложением. Важно: обращение по имени сервиса, а не localhost — контейнеры резолвят друг друга внутри общей Docker-сети.
Проверка: http://localhost:9090, запрос up — если сервис показывает 1, метрики собираются.
6️⃣ Loki + Promtail
Легковесная замена ELK для логов.
Loki — это «Prometheus, но для логов». Не индексирует содержимое целиком (как Elasticsearch), а только метки — за счёт этого жрёт в разы меньше ресурсов. Promtail — агент, который читает файлы логов (tail) и отправляет в Loki. Оба сервиса добавляем в тот же docker-compose.yml.
7️⃣ Grafana
Поднимаем через docker run -d -p 3000:3000 grafana/grafana, заходим на http://localhost:3000 (admin/admin). Добавляем три источника данных: Prometheus (http://prometheus:9090), Zipkin (если нет в списке — ставим плагин из каталога, не путать с Jaeger) и Loki (http://loki:3100).
Дальше — либо импортируем готовый дашборд из каталога Grafana (например, популярный Spring Boot дашборд ID 4701), либо собираем свой из трёх панелей: график RPS и ошибок из Prometheus, список последних трейсов из Zipkin, логи по выбранному traceId из Loki.
Финальная проверка: делаем запрос, который генерирует ошибку. В Grafana находим трейс, кликаем — подтягиваются соответствующие логи. Если связка работает — observability собрана.
Где propagation НЕ работает из коробки: — Kafka / RabbitMQ — gRPC — @Async и кастомные пулы потоков — Apache HttpClient / OkHttp без интерцепторов.
Для Kafka подключаем
micrometer-tracing-integration-kafka.🔵 Бизнес-теги в трейсах (Observation API)
Вместо устаревшего Tracer.currentSpan() в Spring Boot 3.2+ используем:
Observation current = Observation.current();
current.highCardinalityKeyValue("orderId", id);
Spring Boot создаёт Observation для каждого HTTP-запроса автоматически. Но в @Async и Kafka-хендлерах контекста нет — создавайте через Observation.createNotStarted().
Итого: actuator + micrometer + brave + Prometheus + Loki + Zipkin + Grafana = полная observability за полдня.
══════ Навигация ══════
Вакансии • Задачи • Собесы
🐸 Библиотека джависта
#Enterprise