Метрики
Модуль для сбора метрик приложения с помощью Micrometer.
Он создает PrometheusMeterRegistry, подключает к нему метрики компонентов Kora и отдает результат в формате Prometheus через приватный HTTP-сервер.
Это позволяет собирать метрики приложения, JVM, процесса и встроенных интеграций в одном месте и опрашивать их внешней системой наблюдаемости.
Для публикации метрик требуется приватный HTTP-сервер, который отдает их в формате Prometheus.
Для пошагового разбора перед справочным описанием смотрите Наблюдаемость.
Подключение¶
Зависимость build.gradle:
Модуль:
Зависимость build.gradle.kts:
Модуль:
Конфигурация¶
Пример конфигурации пути приватного HTTP-сервера для получения метрик, описанной в классе HttpServerConfig (указаны значения по умолчанию):
Пример полной конфигурации, описанной в классе MetricsConfig (указаны значения по умолчанию):
Метрики модуля¶
Блок metrics выше настраивает реестр глобально. Каждый модуль, собирающий метрики, дополнительно предоставляет собственный
блок telemetry.metrics, описанный в TelemetryConfig.MetricsConfig, который позволяет включать и отключать метрики, настраивать корзины гистограммы
и добавлять дополнительные теги только для этого модуля. В примере ниже в качестве носителя используется модуль HTTP-сервер, но
те же поля telemetry.metrics применяются дословно к HTTP-клиенту, Базе данных,
Kafka, gRPC-серверу, gRPC-клиенту, Планировщику,
Кэшу и любой другой интеграции, которая сообщает метрики:
httpServer {
telemetry {
metrics {
enabled = true //(1)!
slo = [1, 10, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 30000, 60000, 90000] //(2)!
tags { //(3)!
"key1" = "value1"
"key2" = "value2"
}
}
}
}
- Включает сбор метрик для модуля (по умолчанию:
true) - Корзины гистограммы SLO для метрик
DistributionSummary/Timer(по умолчанию:ru.tinkoff.kora.telemetry.common.TelemetryConfig.MetricsConfig#DEFAULT_SLOв миллисекундах дляV120/#DEFAULT_SLO_V123в секундах дляV123) - Дополнительные общие теги, добавляемые к каждой метрике, которую сообщает модуль (по умолчанию:
{})
httpServer:
telemetry:
metrics:
enabled: true #(1)!
slo: [ 1, 10, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 30000, 60000, 90000 ] #(2)!
tags: #(3)!
key1: value1
key2: value2
- Включает сбор метрик для модуля (по умолчанию:
true) - Корзины гистограммы SLO для метрик
DistributionSummary/Timer(по умолчанию:ru.tinkoff.kora.telemetry.common.TelemetryConfig.MetricsConfig#DEFAULT_SLOв миллисекундах дляV120/#DEFAULT_SLO_V123в секундах дляV123) - Дополнительные общие теги, добавляемые к каждой метрике, которую сообщает модуль (по умолчанию:
{})
Установка enabled = false полностью отключает создание метрик для этого модуля (MetricsFactory модуля не возвращает
метрик), что является рекомендованным способом заглушить шумную интеграцию. Значения корзин slo по умолчанию для каждого стандарта
перечислены в разделе Персонализация.
Параметры конфигурации сбора метрик также описаны в модулях, которые собирают метрики: HTTP-сервер, HTTP-клиент, gRPC-сервер, gRPC-клиент, Планировщик, Кэш и другие интеграции.
Использование¶
Kora следует нотации, описанной в спецификации Prometheus.
После подключения модуля PrometheusMeterRegistry регистрируется в Metrics.globalRegistry и используется всеми компонентами, которые собирают метрики.
При остановке приложения этот реестр удаляется из Metrics.globalRegistry и закрывается.
Компонент PrometheusMeterRegistryWrapper является Root-компонентом и реализует Wrapped<PrometheusMeterRegistry>, поэтому пользовательский код может внедрять как обобщенный MeterRegistry, так и конкретный PrometheusMeterRegistry:
Реестр автоматически получает стандартные привязки Micrometer: ClassLoaderMetrics, JvmMemoryMetrics, JvmGcMetrics, JvmThreadMetrics, ProcessorMetrics, FileDescriptorMetrics, UptimeMetrics.
Kora также регистрирует метрику kora.up со значением 1 и тегом version.
Kora дополнительно связывает реестр Micrometer с MeterProvider из OpenTelemetry (MicrometerMeterProvider из io.opentelemetry.contrib.metrics.micrometer), поэтому библиотеки, инструментированные с помощью API метрик OpenTelemetry, публикуют данные через тот же PrometheusMeterRegistry.
Готовый к запуску базовый пример, который связывает MetricsModule вместе с HoconConfigModule, LogbackModule, UndertowHttpServerModule и экспортером OpenTelemetry, доступен в примере kora-java-telemetry.
Экспорт в Prometheus¶
Метрики отдаются в текстовом формате Prometheus приватным HTTP-сервером по пути privateApiHttpMetricsPath (по умолчанию /metrics), обслуживаемому на порту privateApiHttpPort.
У приватного сервера должен быть настроен порт, чтобы маршрут был доступен.
При примерной конфигурации (privateApiHttpPort = 8085) текущий снимок метрик можно получить так:
Направьте цель опроса вашего Prometheus (или любого совместимого сборщика) на тот же хост, порт и путь.
Пользовательская метрика¶
Для пользовательской метрики лучше создать отдельный компонент, внедрить MeterRegistry и переиспользовать созданные экземпляры Meter.
Не создавайте новую метрику при каждом вызове метода: если набор тегов зависит от операции, используйте ключ с ограниченной кардинальностью и кэшируйте метрику в ConcurrentHashMap.
Вызов register(...) нужен для первоначальной регистрации метрики в MeterRegistry; на горячем пути предпочтительнее использовать уже созданный Timer / Counter / Gauge и вызывать только record(...) или increment(...).
Kora использует такой же подход для своих внутренних метрик.
Например, метрика длительности внешней операции:
@Component
public final class ExternalOperationMetrics {
private record Key(String operation, String status) {}
private final MeterRegistry meterRegistry;
private final ConcurrentHashMap<Key, Timer> timers = new ConcurrentHashMap<>();
public ExternalOperationMetrics(MeterRegistry meterRegistry) {
this.meterRegistry = meterRegistry;
}
public void record(String operation, String status, long durationNanos) {
var key = new Key(operation, status);
var timer = this.timers.computeIfAbsent(key, k -> Timer.builder("external.operation.duration")
.tag("operation", k.operation())
.tag("status", k.status())
.register(this.meterRegistry));
timer.record(durationNanos, TimeUnit.NANOSECONDS);
}
}
@Component
class ExternalOperationMetrics(
private val meterRegistry: MeterRegistry
) {
private data class Key(
val operation: String,
val status: String
)
private val timers = ConcurrentHashMap<Key, Timer>()
fun record(operation: String, status: String, durationNanos: Long) {
val key = Key(operation, status)
val timer = timers.computeIfAbsent(key) {
Timer.builder("external.operation.duration")
.tag("operation", it.operation)
.tag("status", it.status)
.register(meterRegistry)
}
timer.record(durationNanos, TimeUnit.NANOSECONDS)
}
}
Значения тегов должны иметь ограниченное число вариантов. Не используйте в качестве тегов идентификаторы пользователей, номера запросов, полный текст ошибки или другие значения с высокой кардинальностью.
Персонализация¶
Чтобы изменить конфигурацию PrometheusMeterRegistry, добавьте в контейнер PrometheusMeterRegistryInitializer.
Инициализатор получает созданный реестр до регистрации стандартных системных метрик, поэтому он может добавить общие теги, MeterFilter, правила переименования или пользовательские настройки PrometheusMeterRegistry.
Важно, PrometheusMeterRegistryInitializer применяется только один раз при инициализации приложения.
Например, мы хотим добавить общий тег для всех метрик:
У стандартных метрик также есть собственные настройки, например корзины гистограммы slo для метрик DistributionSummary/Timer, настраиваемые для каждого модуля в блоке telemetry.metrics.
Когда slo не переопределено, значения по умолчанию зависят от выбранного стандарта OpenTelemetry:
V120—DEFAULT_SLOв миллисекундах:1, 10, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 30000, 60000, 90000V123—DEFAULT_SLO_V123в секундах:0.001, 0.010, 0.050, 0.100, 0.200, 0.500, 1, 2, 5, 10, 20, 30, 60, 90
Оба массива объявлены в ru.tinkoff.kora.telemetry.common.TelemetryConfig.MetricsConfig; имена полей глобального реестра находятся в ru.tinkoff.kora.micrometer.module.MetricsConfig.
Поставщики тегов¶
Набор тегов, прикрепляемых к метрикам фреймворка, формируется поставщиками тегов для каждого модуля, зарегистрированными как @DefaultComponent.
Чтобы изменить, какие теги выдаются для конкретной интеграции, предоставьте собственную реализацию соответствующего интерфейса в качестве переопределения @DefaultComponent:
MicrometerHttpServerTagsProvider(пакетru.tinkoff.kora.micrometer.module.http.server.tag) — метрики HTTP-сервераMicrometerHttpClientTagsProvider(пакетru.tinkoff.kora.micrometer.module.http.client.tag) — метрики HTTP-клиентаMicrometerGrpcServerTagsProvider/MicrometerGrpcClientTagsProvider(пакеты...grpc.server.tag/...grpc.client.tag) — метрики gRPCMicrometerKafkaConsumerTagsProvider/MicrometerKafkaProducerTagsProvider(пакеты...kafka.consumer.tag/...kafka.producer.tag) — метрики Kafka
Поставщик по умолчанию выбирается по значению metrics.opentelemetrySpec, поэтому переопределение заменяет сопоставление тегов для обоих стандартов.
Стандарт¶
Изначально формат метрик использовал стандарт V120 из OpenTelemetry; начиная с Kora 1.1.0 метрики также могут предоставляться
в стандарте V123 из OpenTelemetry. Частичный список изменений доступен в документации OpenTelemetry
и в руководстве по миграции OpenTelemetry.
Параметр metrics.opentelemetrySpec влияет на некоторые имена метрик, единицы измерения и наборы тегов.
Справочник ниже перечисляет варианты как V120, так и V123 для таких метрик; если вариант не указан, имя одинаково для обоих стандартов.
Справочник метрик¶
Все метрики Kora используют семантические соглашения OpenTelemetry для именования и тегов.
Используемые типы метрик Micrometer:
- DistributionSummary — используется для сбора распределений произвольных значений. Этот тип метрики обеспечивает эффективную визуализацию данных по корзинам и вычисление процентилей.
- Counter — монотонно возрастающий счетчик
- Gauge — текущее значение метрики
- Timer — длительность операции с поддержкой count, sum, max и корзин
HTTP-сервер¶
| Метрика | Prometheus | Тип | Описание | Теги |
|---|---|---|---|---|
http.server.duration (V120), http.server.request.duration (V123) |
http_server_duration_milliseconds (V120) / http_server_request_duration_seconds (V123) / _count / _sum / _bucket / _max |
DistributionSummary | Длительность обработки запроса HTTP-сервером |
V120: http.request.method, http.response.status_code, http.route, server.address, url.scheme, http.target, http.method, http.status_code; V123: http.request.method, http.response.status_code, http.route, url.scheme, server.address, error.type |
http.server.active_requests |
http_server_active_requests |
Gauge | Количество активных HTTP-запросов |
V120: http.route, http.request.method, server.address, url.scheme, http.target, http.method; V123: http.route, http.request.method, server.address, url.scheme |
Подробнее смотрите в документации модуля HTTP-сервер.
HTTP-клиент¶
| Метрика | Prometheus | Тип | Описание | Теги |
|---|---|---|---|---|
http.client.duration (V120), http.client.request.duration (V123) |
http_client_duration_milliseconds (V120) / http_client_request_duration_seconds (V123) / _count / _sum / _bucket / _max |
DistributionSummary | Длительность запроса HTTP-клиента |
V120: http.request.method, http.response.status_code, server.address, url.scheme, http.route, http.status_code, http.method, http.target, error.type; V123: http.request.method, http.response.status_code, server.address, url.scheme, http.route, http.status_code, error.type |
Подробнее смотрите в документации модуля HTTP-клиент.
База данных¶
| Метрика | Prometheus | Тип | Описание | Теги |
|---|---|---|---|---|
database.client.request.duration (V120), db.client.request.duration (V123) |
database_client_request_duration_milliseconds (V120) / db_client_request_duration_seconds (V123) / _count / _sum / _bucket / _max |
DistributionSummary | Длительность операции/запроса к базе данных | V120: pool, query.id, query.operation, error; V123: db.pool.name, db.statement, db.operation, error.type |
Подробнее смотрите в документации модуля База данных.
Kafka¶
| Метрика | Prometheus | Тип | Описание | Теги |
|---|---|---|---|---|
messaging.receive.duration |
messaging_receive_duration_milliseconds / _count / _sum / _bucket / _max |
DistributionSummary | Длительность обработки одного сообщения | messaging.system, messaging.destination, messaging.operation, error.type |
messaging.publish.duration |
messaging_publish_duration_milliseconds / _count / _sum / _bucket / _max |
DistributionSummary | Длительность отправки сообщения | messaging.system, messaging.destination, messaging.partition_id, error.type |
messaging.process.batch.duration |
messaging_process_batch_duration_milliseconds / _count / _sum / _bucket / _max |
DistributionSummary | Длительность обработки пакета сообщений | messaging.system, messaging.destination, error.type |
messaging.kafka.consumer.lag |
messaging_kafka_consumer_lag |
Gauge | Отставание потребителя по разделу | messaging.system, messaging.destination, messaging.partition_id, messaging.consumer_group |
Подробнее смотрите в документации модуля Kafka.
gRPC-сервер¶
| Метрика | Prometheus | Тип | Описание | Теги |
|---|---|---|---|---|
rpc.server.duration |
rpc_server_duration_milliseconds / _count / _sum / _bucket / _max |
DistributionSummary | Длительность обработки вызова gRPC-сервером | rpc.service, rpc.method, rpc.status, error.type |
rpc.server.requests_per_rpc |
rpc_server_requests_per_rpc_total |
Counter | Количество запросов, полученных за один RPC | rpc.service, rpc.method |
rpc.server.responses_per_rpc |
rpc_server_responses_per_rpc_total |
Counter | Количество ответов, отправленных за один RPC | rpc.service, rpc.method |
Подробнее смотрите в документации модуля gRPC-сервер.
gRPC-клиент¶
| Метрика | Prometheus | Тип | Описание | Теги |
|---|---|---|---|---|
rpc.client.duration |
rpc_client_duration_milliseconds / _count / _sum / _bucket / _max |
DistributionSummary | Длительность вызова gRPC-клиента | rpc.service, rpc.method, rpc.status, error.type, server.address |
rpc.client.requests_per_rpc |
rpc_client_requests_per_rpc_total |
Counter | Количество запросов, отправленных за один RPC | rpc.service, rpc.method, server.address |
rpc.client.responses_per_rpc |
rpc_client_responses_per_rpc_total |
Counter | Количество ответов, полученных за один RPC | rpc.service, rpc.method, server.address |
Подробнее смотрите в документации модуля gRPC-клиент.
SOAP-клиент¶
| Метрика | Prometheus | Тип | Описание | Теги |
|---|---|---|---|---|
rpc.client.duration |
rpc_client_duration_milliseconds / _count / _sum / _bucket / _max |
DistributionSummary | Длительность вызова SOAP-клиента | rpc.system, rpc.service, rpc.method, rpc.result, server.address, server.port |
Подробнее смотрите в документации модуля SOAP-клиент.
Планировщик¶
| Метрика | Prometheus | Тип | Описание | Теги |
|---|---|---|---|---|
scheduling.job.duration |
scheduling_job_duration_milliseconds / _count / _sum / _bucket / _max |
DistributionSummary | Длительность выполнения запланированной задачи | code.class, code.function, error.type |
Подробнее смотрите в документации модуля Планировщик.
Кэш¶
| Метрика | Prometheus | Тип | Описание | Теги |
|---|---|---|---|---|
cache.duration |
cache_duration_seconds / _count / _sum / _bucket / _max |
Timer | Длительность операции с кэшем (GET, SET, DELETE и другие) |
cache, operation, origin, status |
cache.ratio |
cache_ratio_total |
Counter | Счетчик попаданий/промахов кэша | cache, origin, type |
cache.hit, cache.miss |
cache_hit_total, cache_miss_total |
Counter | Устаревшие счетчики попаданий/промахов, сохраненные для совместимости | cache, origin |
Стандартные метрики Micrometer регистрируются автоматически при использовании Caffeine:
| Метрика | Prometheus | Тип | Описание |
|---|---|---|---|
cache.gets |
cache_gets_total |
Counter | Количество обращений к кэшу |
cache.puts |
cache_puts_total |
Counter | Количество записей в кэш |
cache.evictions |
cache_evictions_total |
Counter | Количество вытеснений из кэша |
cache.size |
cache_size |
Gauge | Текущий размер кэша |
Подробнее смотрите в документации модуля Кэш.
Redis / Lettuce¶
| Метрика | Prometheus | Тип | Описание | Теги |
|---|---|---|---|---|
lettuce.command.completion.duration |
lettuce_command_completion_duration_milliseconds / _count / _sum / _bucket / _max |
DistributionSummary | Длительность завершения команды Redis | type, remote, local, command, error.type |
lettuce.command.firstresponse.duration |
lettuce_command_firstresponse_duration_milliseconds / _count / _sum / _bucket / _max |
DistributionSummary | Длительность первого ответа на команду Redis | type, remote, local, command, error.type |
Отказоустойчивость¶
| Метрика | Prometheus | Тип | Описание | Теги |
|---|---|---|---|---|
resilient.circuitbreaker.state |
resilient_circuitbreaker_state |
Gauge | Состояние предохранителя (0=CLOSED, 1=HALF_OPEN, 2=OPEN) | name |
resilient.circuitbreaker.transition |
resilient_circuitbreaker_transition_total |
Counter | Переходы состояний предохранителя | name, state |
resilient.circuitbreaker.call.acquire |
resilient_circuitbreaker_call_acquire_total |
Counter | Попытки/отклонения захвата вызова предохранителем | name, state, status |
resilient.retry.attempts |
resilient_retry_attempts_total |
Counter | Количество повторных попыток | name |
resilient.retry.exhausted |
resilient_retry_exhausted_total |
Counter | Количество исчерпанных повторов | name |
resilient.timeout.exhausted |
resilient_timeout_exhausted_total |
Counter | Количество таймаутов | name |
resilient.fallback.attempts |
resilient_fallback_attempts_total |
Counter | Количество вызовов резервного варианта | name, type |
Подробнее смотрите в документации модуля Отказоустойчивость.
JMS¶
| Метрика | Prometheus | Тип | Описание | Теги |
|---|---|---|---|---|
messaging.receive.duration |
messaging_receive_duration_milliseconds / _count / _sum / _bucket / _max |
DistributionSummary | Длительность получения сообщения JMS | messaging.system, messaging.destination.name, error.type |
S3-клиент¶
| Метрика | Prometheus | Тип | Описание | Теги |
|---|---|---|---|---|
s3.client.duration |
s3_client_duration_milliseconds / _count / _sum / _bucket / _max |
DistributionSummary | Длительность HTTP-запроса к S3 | aws.s3.bucket, aws.operation.name, error.type |
s3.kora.client.duration |
s3_kora_client_duration_milliseconds / _count / _sum / _bucket / _max |
DistributionSummary | Длительность операции S3-клиента Kora | aws.client.name, aws.s3.bucket, aws.operation.name, error.type |
Подробнее смотрите в документации модуля S3-клиент.
Camunda 7 BPMN¶
| Метрика | Prometheus | Тип | Описание | Теги |
|---|---|---|---|---|
camunda.engine.delegate.duration |
camunda_engine_delegate_duration_milliseconds / _count / _sum / _bucket / _max |
DistributionSummary | Длительность выполнения Java-делегата Camunda BPMN | delegate, business.key, error.type |
camunda.engine.delegate.active_requests |
camunda_engine_delegate_active_requests |
Gauge | Количество активных выполнений делегата | delegate, business.key |
Подробнее смотрите в документации модуля Camunda 7 BPMN.
Camunda REST¶
| Метрика | Prometheus | Тип | Описание | Теги |
|---|---|---|---|---|
camunda.rest.server.duration (V120), camunda.rest.server.request.duration (V123) |
camunda_rest_server_duration_milliseconds (V120) / camunda_rest_server_request_duration_seconds (V123) / _count / _sum / _bucket / _max |
DistributionSummary | Длительность запроса Camunda REST |
V120: http.request.method, http.response.status_code, http.route, server.address, url.scheme, http.target, http.method, http.status_code; V123: http.request.method, http.response.status_code, http.route, url.scheme, server.address, error.type |
camunda.rest.server.active_requests |
camunda_rest_server_active_requests |
Gauge | Количество активных запросов Camunda REST | http.route, http.request.method, server.address, url.scheme |
Подробнее смотрите в документации модуля Camunda 7 REST.
Camunda 8 Worker¶
| Метрика | Prometheus | Тип | Описание | Теги |
|---|---|---|---|---|
zeebe.worker.handler (V120), zeebe.worker.handler.duration (V123) |
zeebe_worker_handler_seconds (V120) / zeebe_worker_handler_duration_seconds (V123) / _count / _sum / _bucket / _max |
DistributionSummary | Длительность обработчика задачи Zeebe Worker |
job.name, job.type, status, error, error.code |
zeebe.worker.handler |
zeebe_worker_handler_total |
Counter | Счетчик ошибок Zeebe Worker |
job.name, job.type, status, error.code |
zeebe.client.worker.job |
zeebe_client_worker_job_total |
Counter | Количество активированных и обработанных задач Zeebe |
action, type |
Подробнее смотрите в документации модуля Camunda 8 Worker.
Система¶
| Метрика | Prometheus | Тип | Описание | Теги |
|---|---|---|---|---|
kora.up |
kora_up |
Gauge | Индикатор состояния фреймворка (значение = 1) | version |
JVM¶
Стандартные метрики JVM собираются автоматически через Micrometer:
| Метрика | Prometheus | Тип | Описание | Теги |
|---|---|---|---|---|
jvm.gc.pause |
jvm_gc_pause_milliseconds / _count / _sum / _max |
DistributionSummary | Длительность паузы GC | action, cause |
jvm.gc.memory.allocated |
jvm_gc_memory_allocated_bytes_total |
Counter | Размер выделенной памяти | — |
jvm.gc.memory.promoted |
jvm_gc_memory_promoted_bytes_total |
Counter | Память, повышенная в старое поколение | — |
jvm.gc.max.data.size |
jvm_gc_max_data_size_bytes |
Gauge | Максимальный размер старого поколения | — |
jvm.gc.live.data.size |
jvm_gc_live_data_size_bytes |
Gauge | Размер старого поколения после полной сборки GC | — |
jvm.memory.used |
jvm_memory_used_bytes |
Gauge | Используемая память | area, id |
jvm.memory.committed |
jvm_memory_committed_bytes |
Gauge | Зарезервированная память JVM | area, id |
jvm.memory.max |
jvm_memory_max_bytes |
Gauge | Максимально доступная память | area, id |
jvm.threads.live |
jvm_threads_live_threads |
Gauge | Количество живых потоков | — |
jvm.threads.daemon |
jvm_threads_daemon_threads |
Gauge | Количество потоков-демонов | — |
jvm.threads.peak |
jvm_threads_peak_threads |
Gauge | Пиковое количество потоков | — |
jvm.threads.states |
jvm_threads_states_threads |
Gauge | Количество потоков по состоянию | state |
process.cpu.usage |
process_cpu_usage |
Gauge | Использование CPU процессом | — |
system.cpu.usage |
system_cpu_usage |
Gauge | Использование CPU системой | — |
system.cpu.count |
system_cpu_count |
Gauge | Количество доступных процессоров | — |
logback.events |
logback_events_total |
Counter | Количество событий логирования | level |
jvm.classes.loaded |
jvm_classes_loaded_classes |
Gauge | Количество загруженных классов | — |
jvm.classes.unloaded |
jvm_classes_unloaded_classes_total |
Counter | Количество выгруженных классов | — |
process.files.open |
process_files_open_files |
Gauge | Количество открытых файловых дескрипторов | — |
process.files.max |
process_files_max_files |
Gauge | Максимальное количество файловых дескрипторов | — |
process.uptime |
process_uptime_milliseconds |
Gauge | Время работы процесса | — |