Как устроены 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.
- Называет реальные риски, диагностику и критерий корректности.
- Связывает ответ с текущей документацией и миграционными ограничениями.