[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"question-nablyudaemost-kak-nastroit-distributed-tracing-v-spring-boot":3},{"id":4,"slug":5,"topicId":6,"topicSlug":7,"topicName":8,"topicEmoji":9,"question":10,"answer":11,"codeLang":12,"codeSrc":12,"important":12,"commonMistakes":12,"modernUsage":12,"difficulty":13,"tags":14,"related":16,"progress":17,"seo":18},766,"kak-nastroit-distributed-tracing-v-spring-boot",20,"nablyudaemost","Наблюдаемость","📊","Как настроить distributed tracing в Spring Boot?","Начиная с Spring Boot 3.x, для distributed tracing используется Micrometer Tracing (замена Spring Cloud Sleuth). Micrometer Tracing предоставляет фасад, а конкретная реализация (OTel или Brave\u002FZipkin) подключается как bridge.\n\n\u003Cdetails>\u003Csummary>Подключение зависимостей (pom.xml)\u003C\u002Fsummary>\n\n```xml\n\u003Cdependencies>\n    \u003C!-- Actuator (обязательно) -->\n    \u003Cdependency>\n        \u003CgroupId>org.springframework.boot\u003C\u002FgroupId>\n        \u003CartifactId>spring-boot-starter-actuator\u003C\u002FartifactId>\n    \u003C\u002Fdependency>\n\n    \u003C!-- Micrometer Tracing — фасад -->\n    \u003Cdependency>\n        \u003CgroupId>io.micrometer\u003C\u002FgroupId>\n        \u003CartifactId>micrometer-tracing\u003C\u002FartifactId>\n    \u003C\u002Fdependency>\n\n    \u003C!-- Bridge к OpenTelemetry -->\n    \u003Cdependency>\n        \u003CgroupId>io.micrometer\u003C\u002FgroupId>\n        \u003CartifactId>micrometer-tracing-bridge-otel\u003C\u002FartifactId>\n    \u003C\u002Fdependency>\n\n    \u003C!-- OTLP exporter для отправки трейсов -->\n    \u003Cdependency>\n        \u003CgroupId>io.opentelemetry\u003C\u002FgroupId>\n        \u003CartifactId>opentelemetry-exporter-otlp\u003C\u002FartifactId>\n    \u003C\u002Fdependency>\n\n    \u003C!-- Для Prometheus метрик с exemplars -->\n    \u003Cdependency>\n        \u003CgroupId>io.micrometer\u003C\u002FgroupId>\n        \u003CartifactId>micrometer-registry-prometheus\u003C\u002FartifactId>\n    \u003C\u002Fdependency>\n\u003C\u002Fdependencies>\n```\n\n\u003C\u002Fdetails>\n\n### Конфигурация application.yml\n\n```yaml\nspring:\n  application:\n    name: order-service\n\nmanagement:\n  tracing:\n    sampling:\n      probability: 1.0          # 1.0 = 100% для dev, 0.1 = 10% для prod\n    propagation:\n      type: w3c                  # W3C Trace Context (по умолчанию)\n  otlp:\n    tracing:\n      endpoint: http:\u002F\u002Fotel-collector:4318\u002Fv1\u002Ftraces\n  metrics:\n    distribution:\n      percentiles-histogram:\n        http.server.requests: true\n    tags:\n      application: ${spring.application.name}\n\nlogging:\n  pattern:\n    console: \"%d{yyyy-MM-dd HH:mm:ss} [%thread] [%X{traceId}\u002F%X{spanId}] %-5level %logger{36} - %msg%n\"\n```\n\n### Автоматическое распространение контекста\n\nSpring Boot автоматически передаёт trace context через:\n- **RestTemplate** \u002F **WebClient** — HTTP-заголовки `traceparent`\n- **Spring Kafka** — Kafka Record Headers\n- **Spring AMQP** — RabbitMQ message headers\n- **Spring gRPC** — gRPC metadata\n\n```java\n@Service\npublic class OrderService {\n    private final RestClient restClient;\n\n    public OrderService(RestClient.Builder builder) {\n        this.restClient = builder\n            .baseUrl(\"http:\u002F\u002Finventory-service:8080\")\n            .build();\n    }\n\n    public InventoryResponse checkStock(String productId) {\n        \u002F\u002F traceId\u002FspanId автоматически передаются в заголовках\n        return restClient.get()\n            .uri(\"\u002Fapi\u002Finventory\u002F{id}\", productId)\n            .retrieve()\n            .body(InventoryResponse.class);\n    }\n}\n```\n\n### Кастомные спаны с Observation API\n\n```java\n@Service\npublic class OrderService {\n    private final ObservationRegistry observationRegistry;\n\n    public OrderService(ObservationRegistry observationRegistry) {\n        this.observationRegistry = observationRegistry;\n    }\n\n    public Order processOrder(OrderRequest request) {\n        return Observation.createNotStarted(\"order.processing\", observationRegistry)\n            .lowCardinalityKeyValue(\"order.type\", request.getType())\n            .highCardinalityKeyValue(\"order.id\", request.getId())\n            .observe(() -> {\n                \u002F\u002F Автоматически создаёт:\n                \u002F\u002F 1. Span с именем \"order.processing\"\n                \u002F\u002F 2. Timer-метрику \"order.processing\"\n                Order order = createOrder(request);\n                validateOrder(order);\n                return order;\n            });\n    }\n}\n```\n\n### Аннотация @Observed\n\n```java\n@Configuration\npublic class ObservationConfig {\n    @Bean\n    public ObservedAspect observedAspect(ObservationRegistry registry) {\n        return new ObservedAspect(registry);\n    }\n}\n\n@Service\npublic class PaymentService {\n    @Observed(name = \"payment.process\",\n              contextualName = \"processing-payment\",\n              lowCardinalityKeyValues = {\"payment.provider\", \"stripe\"})\n    public PaymentResult processPayment(PaymentRequest request) {\n        \u002F\u002F Автоматически создаётся span + метрика\n        return callPaymentProvider(request);\n    }\n}\n```\n\n### Логирование с traceId\n\nMicrometer Tracing автоматически добавляет `traceId` и `spanId` в MDC (Mapped Diagnostic Context):\n\n```java\n@Service\npublic class OrderService {\n    private static final Logger log = LoggerFactory.getLogger(OrderService.class);\n\n    public Order processOrder(OrderRequest request) {\n        \u002F\u002F traceId\u002FspanId автоматически добавляются через MDC\n        log.info(\"Processing order for customer: {}\", request.getCustomerId());\n        \u002F\u002F Лог: 2026-04-22 10:30:00 [main] [abc123\u002Fdef456] INFO  OrderService - Processing order...\n        return doProcess(request);\n    }\n}\n```\n\n\u003Cdetails>\u003Csummary>Конфигурация logback для JSON-формата\u003C\u002Fsummary>\n\n```xml\n\u003C!-- logback-spring.xml -->\n\u003Cconfiguration>\n    \u003Cappender name=\"CONSOLE\" class=\"ch.qos.logback.core.ConsoleAppender\">\n        \u003Cencoder class=\"net.logstash.logback.encoder.LogstashEncoder\">\n            \u003CincludeMdcKeyName>traceId\u003C\u002FincludeMdcKeyName>\n            \u003CincludeMdcKeyName>spanId\u003C\u002FincludeMdcKeyName>\n        \u003C\u002Fencoder>\n    \u003C\u002Fappender>\n    \u003Croot level=\"INFO\">\n        \u003Cappender-ref ref=\"CONSOLE\" \u002F>\n    \u003C\u002Froot>\n\u003C\u002Fconfiguration>\n```\n\nРезультат:\n```json\n{\n  \"@timestamp\": \"2026-04-22T10:30:00.123Z\",\n  \"level\": \"INFO\",\n  \"logger_name\": \"com.example.OrderService\",\n  \"message\": \"Processing order for customer: 42\",\n  \"traceId\": \"abc123def456789\",\n  \"spanId\": \"def456789abc\",\n  \"service\": \"order-service\"\n}\n```\n\n\u003C\u002Fdetails>\n\n### Важное\n- **Micrometer Tracing** — фасад, аналогичный SLF4J. Нужен bridge (`micrometer-tracing-bridge-otel`) для конкретной реализации.\n- **Observation API** — единый механизм, создающий одновременно метрику и span. Используйте `@Observed` вместо отдельных `@Timed` + ручных спанов.\n- **sampling.probability** = 1.0 в dev\u002Fstaging, 0.01-0.1 в production. В production используйте tail-based sampling на стороне OTel Collector.\n- Spring Boot 3.x автоматически пропагирует контекст через стандартные HTTP-клиенты, Kafka, RabbitMQ.\n\n### Частые ошибки\n- **Забыть подключить bridge**: без `micrometer-tracing-bridge-otel` трейсы не генерируются.\n- **sampling.probability = 1.0 в production**: 100% семплирование на высоконагруженном сервисе создаёт огромный overhead.\n- **Потеря контекста в `@Async`**: стандартный `TaskExecutor` не передаёт trace context. Используйте `ContextPropagatingTaskDecorator`.\n- **Не добавить traceId в логи**: без `%X{traceId}` в log pattern невозможно связать логи с трейсами.\n- **Путать Spring Cloud Sleuth и Micrometer Tracing**: Sleuth устарел и не поддерживается в Spring Boot 3.x.\n\n\u003Cdetails>\u003Csummary>Правильная передача контекста в @Async\u003C\u002Fsummary>\n\n```java\n@Configuration\n@EnableAsync\npublic class AsyncConfig implements AsyncConfigurer {\n\n    private final ObservationRegistry observationRegistry;\n\n    public AsyncConfig(ObservationRegistry observationRegistry) {\n        this.observationRegistry = observationRegistry;\n    }\n\n    @Override\n    public Executor getAsyncExecutor() {\n        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();\n        executor.setCorePoolSize(5);\n        executor.setMaxPoolSize(10);\n        executor.setTaskDecorator(new ContextPropagatingTaskDecorator());\n        executor.initialize();\n        return executor;\n    }\n}\n```\n\n\u003C\u002Fdetails>\n\n### Как используется в 2026\n- **Micrometer Observation API** — стандартный способ инструментирования в Spring-экосистеме.\n- **OTLP экспорт** — нативная поддержка в Spring Boot через `management.otlp.tracing` и `management.otlp.metrics`.\n- **Виртуальные потоки (Project Loom)** — Micrometer Context Propagation корректно работает с virtual threads.\n- **Spring Boot 3.4+** — улучшенная поддержка OTel Logs, автоматическая корреляция логов с трейсами через OTLP.\n- **Testcontainers + OTel** — интеграционные тесты с реальным OTel Collector для проверки трейсинга.\n\n> **На собеседовании:** обязательно упомяните переход от Spring Cloud Sleuth к Micrometer Tracing в Spring Boot 3.x. Покажите знание Observation API как единого механизма для метрик и трейсов. Ключевая ошибка на собеседовании — не знать про необходимость bridge и `ContextPropagatingTaskDecorator` для `@Async`.","","middle",[15],"observability",[],null,{"title":19,"description":20,"ogTitle":19,"ogDescription":21,"keywords":22,"schemaAnswer":23,"featuredSnippetReady":24},"Как настроить distributed tracing в Spring Boot? — Gymterview","Начиная с Spring Boot 3.x, для distributed tracing используется Micrometer Tracing (замена Spring Cloud Sleuth). Micrometer Tracing предоставляет фасад, а конкр","Начиная с Spring Boot 3.x, для distributed tracing используется Micrometer Tracing (замена Spring Cloud Sleuth). Microme",[15,13],"Начиная с Spring Boot 3.x, для distributed tracing используется Micrometer Tracing (замена Spring Cloud Sleuth). Micrometer Tracing предоставляет фасад, а конкретная реализация (OTel или Brave\u002FZipkin) подключается как bridge.",true]