Spring BootSeniorTechnical

Как устроены Actuator metrics/tracing и как подключить OpenTelemetry?

Actuator предоставляет метрики через Micrometer (эндпоинт /actuator/prometheus) и трассировку через Micrometer Tracing. Для OpenTelemetry подключите micrometer-tracing-bridge-otel и настройте OTLP экспортёр.

Actuator metrics, tracing и интеграция с OpenTelemetry

Spring Boot Actuator предоставляет готовую инфраструктуру для метрик и трассировки. С версии 3.x метрики реализованы через Micrometer, трассировка — через Micrometer Tracing (обёртка над Brave/OpenTelemetry).

Метрики: Micrometer + Prometheus

Добавьте зависимости в build.gradle:

implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'io.micrometer:micrometer-registry-prometheus'

Конфигурация в application.yml:

management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics,prometheus
  metrics:
    tags:
      application: my-service
      environment: production
  endpoint:
    health:
      show-details: always

После старта GET /actuator/prometheus отдаёт метрики в формате Prometheus. Стандартные метрики включают JVM (heap, GC, threads), HTTP запросы (http.server.requests), пул соединений HikariCP, кэши.

Кастомные метрики через MeterRegistry

@Service
public class OrderService {

    private final Counter ordersCreated;
    private final Timer orderProcessingTime;

    public OrderService(MeterRegistry registry) {
        this.ordersCreated = Counter.builder("orders.created")
            .description("Total orders created")
            .tag("type", "online")
            .register(registry);
        this.orderProcessingTime = Timer.builder("orders.processing.time")
            .description("Order processing duration")
            .register(registry);
    }

    public Order createOrder(OrderRequest req) {
        return orderProcessingTime.record(() -> {
            Order order = processOrder(req);
            ordersCreated.increment();
            return order;
        });
    }
}

Трассировка: Micrometer Tracing + OpenTelemetry

Зависимости для OpenTelemetry экспортёра в OTLP (OpenTelemetry Protocol):

implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'io.micrometer:micrometer-tracing-bridge-otel'
implementation 'io.opentelemetry.instrumentation:opentelemetry-spring-boot-starter'
implementation 'io.opentelemetry:opentelemetry-exporter-otlp'

Конфигурация трассировки:

management:
  tracing:
    sampling:
      probability: 1.0   # 100% в dev, 0.1 в prod
  otlp:
    tracing:
      endpoint: http://otel-collector:4318/v1/traces

spring:
  application:
    name: order-service

Метрики через OTLP в OpenTelemetry Collector

Для отправки метрик в OTLP (вместо Prometheus scrape):

implementation 'io.micrometer:micrometer-registry-otlp'
management:
  otlp:
    metrics:
      export:
        url: http://otel-collector:4318/v1/metrics
        step: 30s

OpenTelemetry Collector конфигурация

receivers:
  otlp:
    protocols:
      http:
        endpoint: 0.0.0.0:4318

exporters:
  prometheus:
    endpoint: 0.0.0.0:8889
  jaeger:
    endpoint: jaeger:14250
    tls:
      insecure: true

service:
  pipelines:
    metrics:
      receivers: [otlp]
      exporters: [prometheus]
    traces:
      receivers: [otlp]
      exporters: [jaeger]

Добавление span-атрибутов вручную

@Service
public class PaymentService {

    private final Tracer tracer;

    public void processPayment(String orderId, BigDecimal amount) {
        Span span = tracer.nextSpan().name("payment.process").start();
        try (Tracer.SpanInScope ws = tracer.withSpan(span)) {
            span.tag("order.id", orderId);
            span.tag("payment.amount", amount.toString());
            // бизнес-логика
        } catch (Exception e) {
            span.error(e);
            throw e;
        } finally {
            span.end();
        }
    }
}

Подводные камни

  • Конфликт Brave и OTel бриджей — нельзя одновременно подключать micrometer-tracing-bridge-brave и micrometer-tracing-bridge-otel; выберите один.
  • sampling.probability=1.0 в prod — 100% sampling при высокой нагрузке создаёт огромный объём данных и деградирует производительность; используйте 0.01–0.1.
  • management.endpoints.web.exposure — по умолчанию открыт только health; забытый prometheus в include означает, что Prometheus не сможет скрейпить метрики.
  • Трассировка не пробрасывается через @Async без настройки TaskDecorator — context propagation обрывается на границе потоков.
  • Имена метрик: Micrometer конвертирует camelCase в kebab.case или нормализует для конкретного реестра; ожидаемое имя в Prometheus может отличаться от заданного в коде.
  • OTLP endpoint у разных инструментов: gRPC порт 4317, HTTP/protobuf порт 4318 — путаница частая причина потери данных.
  • Spring Boot 3.x и OTel автоконфигурация из opentelemetry-spring-boot-starter может конфликтовать с Micrometer Tracing автоконфигурацией — изучите, какие бины переопределяются.

Common mistakes

  • Отвечать определением без production-сценария.
  • Не называть runtime boundary, security boundary или failure mode.
  • Игнорировать версию API, observability и тестовую проверку.

What the interviewer is testing

  • Объясняет механизм своими словами и без выдуманных API.
  • Называет реальные риски, диагностику и критерий корректности.
  • Связывает ответ с текущей документацией и миграционными ограничениями.

Sources

Related topics