Метрики
Модуль для сбора метрик приложения с помощью Micrometer.
Он создает PrometheusMeterRegistry, регистрирует его в контейнере зависимостей как MeterRegistry и отдает собранные значения в формате Prometheus через системный HTTP-сервер.
Это позволяет собирать метрики приложения, JVM, процесса и встроенных интеграций в одном месте и опрашивать их внешней системой наблюдаемости.
Для публикации метрик требуется системный HTTP-сервер, который отдает их в формате Prometheus.
Метрики модулей по умолчанию выключены
TelemetryConfig.MetricsConfig#enabled возвращает false, и это значение наследует каждый модуль.
Приложение, в котором подключен только MetricsModule, стартует нормально и отвечает на /metrics кодом 200,
но в ответе будут лишь значения JVM, процесса и kora.up — никаких http_server_*, http_client_*,
db_* или любых других метрик компонентов. Включайте метрики явно для каждого модуля через
<module>.telemetry.metrics.enabled = true, смотрите Метрики модуля.
Пошаговое руководство перед справочным описанием смотрите в разделе Наблюдаемость.
Подключение¶
Зависимость build.gradle:
Модуль:
Зависимость build.gradle.kts:
Модуль:
MetricsModule находится в пакете io.koraframework.micrometer.module.
Он предоставляет реестр, общие теги приложения и контракт эндпоинта для опроса — сами значения метрик создают подключенные вами модули
(HTTP-сервер, HTTP-клиент, База данных, Kafka и так далее).
Конфигурация¶
Метрики настраиваются в трех местах: общая для приложения секция metrics модуля MetricsModule,
путь и порт эндпоинта опроса на системном сервере, а также блок telemetry.metrics внутри каждого модуля, который сообщает метрики.
Метрики приложения¶
Секция metrics описывается классом MetricsConfig из пакета io.koraframework.micrometer.module (указаны значения по умолчанию):
При metrics.enabled = false модуль MetricsModule предоставляет пустой (no-op) MeterRegistry вместо PrometheusMeterRegistry:
не записываются ни метрики модулей, ни JVM, ни kora.up, ни пользовательские метрики, компоненты PrometheusMeterRegistryInitializer не применяются,
а /metrics отвечает пустым телом. Так метрики отключаются без удаления MetricsModule из приложения,
например в тесте или в локальном профиле.
Этот MetricsConfig — другой класс, не тот TelemetryConfig.MetricsConfig модулей, что описан в разделе Метрики модулей,
и значения по умолчанию у них противоположные: metrics.enabled равен true, а <module>.telemetry.metrics.enabled — false.
Модуль сообщает метрики, только когда включены оба переключателя.
Поставщик общих тегов¶
Если значение тега известно только при старте (имя хоста, регион из окружения, версия сборки),
зарегистрируйте компонент MetricsTagsProvider из пакета io.koraframework.micrometer.module:
Поставщиков можно зарегистрировать сколько угодно. MetricsModule собирает их все, объединяет их теги с metrics.tags
и через PrometheusMeterRegistryInitializer устанавливает на реестр один глобальный MeterFilter.commonTags(...).
При совпадении ключей значение из metrics.tags побеждает любого поставщика.
Теги вычисляются один раз, при создании реестра, поэтому поставщик не должен возвращать значения, зависящие от запроса.
Этот инициализатор — обычный компонент, а не @DefaultComponent, поэтому общие теги применяются и тогда, когда приложение объявляет собственные PrometheusMeterRegistryInitializer: инициализатор общих тегов работает вместе с ними, смотрите Персонализация.
Эндпоинт опроса¶
Пример конфигурации пути системного HTTP-сервера, описанной в классе SystemHttpServerConfig (указаны значения по умолчанию):
- Порт системного
HTTP-сервера, который обслуживает эндпоинт метрик (по умолчанию:8085). - Путь для получения метрик в формате
Prometheus(по умолчанию:"/metrics").
Метрики модуля¶
Каждый модуль, собирающий метрики, предоставляет блок telemetry.metrics, описанный в TelemetryConfig.MetricsConfig,
который позволяет включить метрики, настроить корзины гистограммы и добавить дополнительные теги только для этого модуля.
В примере ниже носителем выступает модуль HTTP-сервер, но те же поля telemetry.metrics применяются дословно к
HTTP-клиенту, Базе данных, Kafka, gRPC-серверу,
gRPC-клиенту, Планировщику, Кэшу, Отказоустойчивости
и любой другой интеграции, которая сообщает метрики:
httpServer {
telemetry {
metrics {
enabled = true //(1)!
slo = ["1ms", "10ms", "50ms", "100ms", "200ms", "500ms", "1s", "2s", "5s", "10s", "20s", "30s", "60s", "90s"] //(2)!
tags { //(3)!
"key1" = "value1"
"key2" = "value2"
}
}
}
}
- Включает сбор метрик для модуля (по умолчанию:
false) - Корзины гистограммы SLO для метрик
Timer, список длительностей (по умолчанию:TelemetryConfig.MetricsConfig#DEFAULT_SLO, перечислен в разделе Персонализация) - Дополнительные общие теги, добавляемые к каждой метрике, которую сообщает модуль (по умолчанию:
{})
httpServer:
telemetry:
metrics:
enabled: true #(1)!
slo: [ "1ms", "10ms", "50ms", "100ms", "200ms", "500ms", "1s", "2s", "5s", "10s", "20s", "30s", "60s", "90s" ] #(2)!
tags: #(3)!
key1: value1
key2: value2
- Включает сбор метрик для модуля (по умолчанию:
false) - Корзины гистограммы SLO для метрик
Timer, список длительностей (по умолчанию:TelemetryConfig.MetricsConfig#DEFAULT_SLO, перечислен в разделе Персонализация) - Дополнительные общие теги, добавляемые к каждой метрике, которую сообщает модуль (по умолчанию:
{})
Значения slo — это длительности: строка несет свою единицу измерения ("1ms", "250ms", "1s", PT1S), а голое число читается как миллисекунды,
поэтому slo = [1, 10, 50] и slo = ["1ms", "10ms", "50ms"] — это один и тот же список.
Оставленное enabled = false (значение по умолчанию) означает, что телеметрия модуля использует Noop-фабрику метрик: ни один Meter не создается и ничего не регистрируется в реестре.
Это же способ заглушить шумную интеграцию после того, как метрики были включены повсеместно.
Метрики создаются только при выполнении обоих условий: подключен MetricsModule (то есть в контейнере есть MeterRegistry)
и у модуля выставлено telemetry.metrics.enabled = true. Если чего-то из этого нет, модуль откатывается на пустую реализацию телеметрии.
Общий для приложения metrics.enabled = false перекрывает оба условия: модуль пишет в пустой MeterRegistry, и ничего не экспортируется.
Пути конфигурации¶
Блок telemetry.metrics вложен в собственную секцию конфигурации модуля:
| Модуль | Путь конфигурации |
|---|---|
| HTTP-сервер (публичный) | httpServer.telemetry.metrics |
| HTTP-сервер (системный) | httpServer.system.telemetry.metrics |
| HTTP-клиент | собственный путь конфигурации клиента из @HttpClient плюс .telemetry.metrics, например httpClient.<clientName>.telemetry.metrics |
| База данных JDBC | jdbc.telemetry.metrics |
| База данных Cassandra | cassandra.telemetry.metrics |
| gRPC-сервер | grpcServer.telemetry.metrics |
| gRPC-клиент | grpcClient.<ServiceName>.telemetry.metrics |
| Планировщик | scheduling.telemetry.metrics |
| Отказоустойчивость | resilient.telemetry.{circuitBreaker,retry,timeout,fallback,rateLimiter}.metrics |
| Kafka | собственный путь конфигурации потребителя или продюсера плюс .telemetry.metrics |
| Кэш | путь конфигурации кэша из @Cache плюс .telemetry.metrics |
| AWS S3-клиент | s3client.aws.telemetry.metrics |
Redis (Lettuce) |
lettuce.telemetry.metrics |
| Camunda 7 BPMN | camunda.engine.bpmn.telemetry.metrics |
| Camunda 7 REST | camunda.rest.telemetry.metrics |
| Camunda 8 Worker | zeebe.worker.telemetry.metrics |
Некоторые модули добавляют рядом с enabled / slo / tags собственные ключи:
- База данных —
driverMetrics(по умолчанию:true) регистрирует в том же реестре метрики пула соединенийHikariCP. - Kafka —
driverMetrics(по умолчанию:false) регистрирует нативные метрики клиентаKafkaчерез биндерKafkaClientMetricsиз Micrometer, с префиксом именkafka.*. - Camunda 7 BPMN —
engineMetrics(по умолчанию:false) включает собственные метрики движкаCamunda.
Параметры сбора метрик также описаны в модулях, которые эти метрики собирают: HTTP-сервер, HTTP-клиент, gRPC-сервер, gRPC-клиент, Планировщик, Кэш и другие интеграции.
Использование¶
Kora следует нотации, описанной в спецификации Prometheus.
После подключения модуля создается PrometheusMeterRegistry, он регистрируется в Metrics.globalRegistry и используется всеми компонентами, которые собирают метрики.
При остановке приложения этот реестр удаляется из Metrics.globalRegistry и закрывается.
Реестр предоставляется компонентом PrometheusMeterRegistryWrapper: это Root-компонент, реализующий Wrapped<MeterRegistry>,
поэтому пользовательский код внедряет контракт MeterRegistry:
Реестр автоматически получает стандартные биндеры Micrometer: ClassLoaderMetrics, JvmMemoryMetrics, JvmGcMetrics, ProcessorMetrics, JvmThreadMetrics, FileDescriptorMetrics, UptimeMetrics.
Они привязываются при создании реестра и не зависят ни от одного флага telemetry.metrics.enabled; убрать их может только общий metrics.enabled = false.
Kora также регистрирует метрику kora.up со значением 1 и тегом version.
Дополнительно Kora связывает реестр Micrometer с MeterProvider из OpenTelemetry (MicrometerMeterProvider из io.opentelemetry.contrib.metrics.micrometer), поэтому библиотеки, инструментированные API метрик OpenTelemetry, публикуют данные через тот же реестр.
Мост объявлен как @DefaultComponent и принимает необязательный компонент CallbackRegistrar, если нужно управлять тем, как опрашиваются асинхронные инструменты.
Готовый к запуску базовый пример, который связывает MetricsModule вместе с HoconConfigModule, LogbackModule, JdbcDatabaseModule, UndertowPublicHttpServerModule и экспортером трассировок OpenTelemetry, доступен в примере kora-java-telemetry.
Экспорт в Prometheus¶
Метрики отдаются в текстовом формате Prometheus системным HTTP-сервером по пути httpServer.system.metricsPath (по умолчанию /metrics) на порту httpServer.system.port (по умолчанию 8085):
Направьте цель опроса вашего Prometheus (или любого совместимого сборщика) на тот же хост, порт и путь.
Эндпоинт всегда отвечает 200. Что именно он вернет, зависит от того, что связано в контейнере:
MetricsModuleподключен — текстовое представление снимка реестра в форматеPrometheus.MetricsModuleподключен, ноmetrics.enabled = false— пустое тело, потому что реестр пустой (no-op).MetricsModuleне подключен — тело# Metric Scraper disabled, потому что компонентаMetricsScraperне существует.- Пользовательский
MeterRegistry, который не являетсяPrometheusMeterRegistry— пустое тело, потому что такой реестр нельзя выгрузить в форматеPrometheus. В этом случае предоставьте собственную реализациюMetricsScraper: она переопределит@DefaultComponent, поставляемыйMetricsModule.
MetricsScraper — это контракт с единственным методом из пакета io.koraframework.telemetry.common:
Пользовательская метрика¶
Для пользовательской метрики лучше создать отдельный компонент, внедрить 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 применяется только один раз при инициализации приложения.
Для общих тегов всех метрик инициализатор не нужен: используйте metrics.tags или MetricsTagsProvider.
Инициализатор нужен для остальных настроек реестра, например для MeterFilter, который отбрасывает ненужные метрики:
У стандартных метрик также есть собственные настройки, например корзины гистограммы slo для метрик Timer, которые задаются для каждого модуля в блоке telemetry.metrics.
Когда slo не переопределено, используется TelemetryConfig.MetricsConfig#DEFAULT_SLO — 14 корзин:
1ms, 10ms, 50ms, 100ms, 200ms, 500ms, 1s, 2s, 5s, 10s, 20s, 30s, 60s, 90s
Массив объявлен в io.koraframework.telemetry.common.TelemetryConfig.MetricsConfig и общий для всех модулей, которые строят Timer.
Фабрики метрик¶
Имена и теги метрик фреймворка формируются фабриками метрик отдельно для каждого модуля — по одному классу Default<Module>MetricsFactory на интеграцию
(пакет <module>.telemetry.impl). Фабрика телеметрии каждого модуля принимает такой класс как необязательную зависимость,
поэтому свой наследник, объявленный компонентом контейнера, заменяет реализацию по умолчанию:
@Component
public final class TenantHttpServerMetricsFactory extends DefaultHttpServerMetricsFactory { //(1)!
@Override
public DefaultHttpServerMetrics create(DefaultHttpServerTelemetry.TelemetryContext context) {
return new TenantHttpServerMetrics(context);
}
private static final class TenantHttpServerMetrics extends DefaultHttpServerMetrics {
private TenantHttpServerMetrics(DefaultHttpServerTelemetry.TelemetryContext context) {
super(context);
}
@Override
protected Timer.Builder createMetricServerDuration(DurationKey metricKey, //(2)!
HttpServerRequest request,
HttpServerResponse response,
@Nullable Throwable throwable) {
return super.createMetricServerDuration(metricKey, request, response, throwable)
.tag("tenant", "default");
}
}
}
- Фабрику подхватывает
HttpServerModule#defaultHttpServerTelemetryFactoryвместо встроеннойDefaultHttpServerMetricsFactory - В билдере допустимы только статические теги — тег, значение которого меняется от запроса к запросу, должен быть частью ключа метрики, иначе разные наборы тегов схлопнутся в один
Meter
@Component
class TenantHttpServerMetricsFactory : DefaultHttpServerMetricsFactory() { //(1)!
override fun create(context: DefaultHttpServerTelemetry.TelemetryContext): DefaultHttpServerMetrics {
return TenantHttpServerMetrics(context)
}
private class TenantHttpServerMetrics(
context: DefaultHttpServerTelemetry.TelemetryContext
) : DefaultHttpServerMetrics(context) {
override fun createMetricServerDuration( //(2)!
metricKey: DurationKey,
request: HttpServerRequest,
response: HttpServerResponse,
throwable: Throwable?
): Timer.Builder {
return super.createMetricServerDuration(metricKey, request, response, throwable)
.tag("tenant", "default")
}
}
}
- Фабрику подхватывает
HttpServerModule#defaultHttpServerTelemetryFactoryвместо встроеннойDefaultHttpServerMetricsFactory - В билдере допустимы только статические теги — тег, значение которого меняется от запроса к запросу, должен быть частью ключа метрики, иначе разные наборы тегов схлопнутся в один
Meter
Тот же приём работает для любой интеграции, имя класса следует за модулем:
DefaultHttpClientMetricsFactory, DefaultDatabaseMetricsFactory, DefaultKafkaConsumerMetricsFactory, DefaultKafkaPublisherMetricsFactory,
DefaultGrpcServerMetricsFactory, DefaultGrpcClientMetricsFactory, DefaultSoapClientMetricsFactory, DefaultSchedulingMetricsFactory,
DefaultCaffeineCacheMetricsFactory, DefaultRedisCacheMetricsFactory, DefaultCircuitBreakerMetricsFactory, DefaultRetryMetricsFactory,
DefaultTimeoutMetricsFactory, DefaultFallbackMetricsFactory, DefaultRateLimiterMetricsFactory, DefaultAwsS3ClientMetricsFactory,
DefaultJmsConsumerMetricsFactory.
Если тег должен зависеть от текущего запроса, добавляйте его в ключ метрики, а не в билдер:
у каждой фабрики для этого есть методы create<Metric>Key(...) и записи-ключи с методом копирования withExtraTags(Tags).
Если дополнительные теги одинаковы для всех метрик модуля, фабрику писать не нужно — используйте ключ конфигурации telemetry.metrics.tags.
Теги, общие для всех метрик приложения, задаются в metrics.tags или через MetricsTagsProvider.
Стандарт¶
Все метрики Kora следуют семантическим соглашениям OpenTelemetry для имен и тегов,
и каждый модуль использует ровно одну схему именования — настраиваемой версии спецификации больше нет.
Ключи тегов берутся из констант атрибутов io.opentelemetry.semconv, поэтому, например, метрика HTTP-сервера несет
http.request.method, http.response.status_code, http.route, url.scheme и error.type.
Имена в экспозиции Prometheus выводятся из имени Micrometer по соглашению об именовании Prometheus:
.заменяется на_;Timerполучает суффикс_seconds, а гистограмма отдается сериями_bucket/_count/_sumплюс отдельный gauge_max;Counterполучает свою базовую единицу измерения и суффикс_total(поэтому метрики, построенные сBaseUnits.OPERATIONS, заканчиваются на_operations_total);Gaugeполучает суффиксом свою базовую единицу измерения, если метрика её объявляет.
Тег error.type всегда присутствует у метрик, которые могут завершиться ошибкой — он содержит каноническое имя класса исключения или пустую строку при успехе.
Справочник метрик¶
Используемые типы метрик Micrometer:
- Timer — длительность операции с поддержкой count, sum, max и корзин гистограммы
- Counter — монотонно возрастающий счетчик
- Gauge — текущее значение метрики
Каждая перечисленная ниже метрика дополнительно несет теги, заданные в telemetry.metrics.tags соответствующего модуля,
и общие теги приложения из metrics.tags и MetricsTagsProvider.
Для тегов исключений error.type использует бинарное имя класса, если у локального или анонимного класса нет канонического имени. После переименования метрик и тегов обновите запросы дашбордов и оповещений.
HTTP-сервер¶
| Метрика | Prometheus | Тип | Описание | Теги |
|---|---|---|---|---|
http.server.request.duration |
http_server_request_duration_seconds / _count / _sum / _bucket / _max |
Timer | Длительность обработки запроса HTTP-сервером |
server.name, server.port, http.request.method, http.response.status_code, http.route, url.scheme, error.type |
http.server.active_requests |
http_server_active_requests |
Gauge | Количество активных HTTP-запросов |
server.name, server.port, http.request.method, http.route, url.scheme |
Тег server.name отличает публичный сервер (kora-undertow) от системного (kora-undertow-system); для запроса, не совпавшего ни с одним маршрутом, http.route равен UNKNOWN_ROUTE.
http.response.status_code — код статуса ответа, поэтому частоту и задержку запросов можно разбить по статусу на http.server.request.duration; у http.server.active_requests тега статуса нет, потому что счетчик увеличивается до появления ответа.
Значения заголовка Host в тегах метрик нет: его задает клиент, и число значений не ограничено, поэтому каждое новое значение создавало бы новую серию. Адрес остается атрибутом server.address у span (см. Трассировка). Если он нужен в метриках, переопределите в собственной фабрике метрик createMetricServerDurationKey и createMetricActiveRequestsGaugeKey и верните ключ через withExtraTags(...) (тег, добавленный только в билдере, не входит в ключ кэша метрик); ограничить набор значений нужно самостоятельно. Нестандартный HTTP-метод попадает в http.request.method как _OTHER.
Подробнее смотрите в документации модуля HTTP-сервер.
HTTP-клиент¶
| Метрика | Prometheus | Тип | Описание | Теги |
|---|---|---|---|---|
http.client.request.duration |
http_client_request_duration_seconds / _count / _sum / _bucket / _max |
Timer | Длительность запроса HTTP-клиента |
http.request.method, http.response.status_code, server.address, server.port, url.scheme, url.template, error.type, system.config, system.name.simple, system.name.canonical |
system.config — путь конфигурации клиента. Теги system.name.simple и system.name.canonical задаются для каждого метода клиента: system.name.canonical — каноническое имя интерфейса декларативного клиента и имя метода (com.example.PetClient.getPet), system.name.simple — только имя метода (getPet).
Одноименные методы разных клиентов получают одинаковый system.name.simple, поэтому различайте клиенты по system.config или system.name.canonical.
Если порт отсутствует в URI, server.port принимает значение 80 для HTTP и 443 для HTTPS; для других схем без явно заданного порта тег не добавляется.
Подробнее смотрите в документации модуля HTTP-клиент.
База данных¶
| Метрика | Prometheus | Тип | Описание | Теги |
|---|---|---|---|---|
db.client.operation.duration |
db_client_operation_duration_seconds / _count / _sum / _bucket / _max |
Timer | Длительность операции/запроса к базе данных | db.client.connection.pool.name, db.system.name, db.query.text, db.operation.name, error.type |
Тег db.system.name берется из строки подключения для JDBC (postgresql, mysql, ...) и равен cassandra для Cassandra.
В db.query.text попадает идентификатор запроса, а не исходный текст SQL.
При telemetry.metrics.driverMetrics = true (значение по умолчанию) пул соединений дополнительно регистрирует в том же реестре собственные метрики:
метрики пула HikariCP для JDBC и метрики драйвера DataStax, отобранные настройкой cassandra.telemetry.metrics, для Cassandra.
Подробнее смотрите в документации модуля База данных.
Kafka¶
| Метрика | Prometheus | Тип | Описание | Теги |
|---|---|---|---|---|
messaging.process.duration |
messaging_process_duration_seconds / _count / _sum / _bucket / _max |
Timer | Длительность обработки одного сообщения | messaging.system, messaging.operation.name, messaging.client.id, messaging.consumer.group.name, messaging.destination.name, messaging.destination.partition.id, error.type, system.config, system.name.simple, system.name.canonical |
messaging.process.batch.duration |
messaging_process_batch_duration_seconds / _count / _sum / _bucket / _max |
Timer | Длительность обработки пакета сообщений | messaging.system, messaging.operation.name, messaging.client.id, messaging.consumer.group.name, error.type, system.config, system.name.simple, system.name.canonical |
messaging.kafka.consumer.lag |
messaging_kafka_consumer_lag |
Gauge | Отставание потребителя по разделу | messaging.system, messaging.client.id, messaging.consumer.group.name, messaging.destination.name, messaging.destination.partition.id, system.config, system.name.simple, system.name.canonical |
messaging.client.operation.duration |
messaging_client_operation_duration_seconds / _count / _sum / _bucket / _max |
Timer | Длительность отправки сообщения | messaging.system, messaging.client.id, messaging.operation.type, messaging.operation.name, messaging.destination.name, messaging.destination.partition.id, error.type, system.config, system.name.simple, system.name.canonical |
messaging.client.sent.messages |
messaging_client_sent_messages_total |
Counter | Количество отправленных сообщений | messaging.system, messaging.client.id, messaging.operation.type, messaging.operation.name, messaging.destination.name, messaging.destination.partition.id, error.type, system.config, system.name.simple, system.name.canonical |
Тег messaging.system всегда равен kafka; messaging.operation.type на стороне продюсера равен send.
Подробнее смотрите в документации модуля Kafka.
gRPC-сервер¶
| Метрика | Prometheus | Тип | Описание | Теги |
|---|---|---|---|---|
rpc.server.call.duration |
rpc_server_call_duration_seconds / _count / _sum / _bucket / _max |
Timer | Длительность обработки вызова gRPC-сервером | server.name, server.port, rpc.system.name, rpc.service, rpc.method, rpc.response.status_code, error.type |
Подробнее смотрите в документации модуля gRPC-сервер.
gRPC-клиент¶
| Метрика | Prometheus | Тип | Описание | Теги |
|---|---|---|---|---|
rpc.client.call.duration |
rpc_client_call_duration_seconds / _count / _sum / _bucket / _max |
Timer | Длительность вызова gRPC-клиента | rpc.system.name, rpc.service, rpc.method, rpc.response.status_code, server.address, server.port, error.type |
Тег rpc.system.name равен grpc и для gRPC-сервера, и для gRPC-клиента.
rpc.response.status_code содержит имя статуса gRPC (например, OK или UNAVAILABLE).
Подробнее смотрите в документации модуля gRPC-клиент.
SOAP-клиент¶
| Метрика | Prometheus | Тип | Описание | Теги |
|---|---|---|---|---|
rpc.client.call.duration |
rpc_client_call_duration_seconds / _count / _sum / _bucket / _max |
Timer | Длительность вызова SOAP-клиента | rpc.system.name, rpc.service, rpc.method, server.address, server.port, http.response.status_code, error.type, soap.fault.code, system.config, system.name.simple, system.name.canonical |
Тег rpc.system.name равен soap; в soap.fault.code попадает код ошибки SOAP, и он пуст, если вызов не вернул fault.
Подробнее смотрите в документации модуля SOAP-клиент.
Планировщик¶
| Метрика | Prometheus | Тип | Описание | Теги |
|---|---|---|---|---|
scheduling.job.duration |
scheduling_job_duration_seconds / _count / _sum / _bucket / _max |
Timer | Длительность выполнения запланированной задачи | code.function.name, system.name.simple, system.name.canonical, error.type, а также system.config, если у задачи объявлен путь конфигурации |
Подробнее смотрите в документации модуля Планировщик.
Кэш¶
Распределенные кэши Redis сообщают собственные метрики операций:
| Метрика | Prometheus | Тип | Описание | Теги |
|---|---|---|---|---|
cache.operation.duration |
cache_operation_duration_seconds / _count / _sum / _bucket / _max |
Timer | Длительность операции с кэшем (GET, PUT, INVALIDATE и другие) |
cache.origin, cache.operation, error.type, system.config, system.name.simple, system.name.canonical |
cache.requests |
cache_requests_total |
Counter | Счетчик попаданий/промахов кэша | cache.origin, cache.operation, cache.result, system.config, system.name.simple, system.name.canonical |
Тег cache.origin равен redis, cache.operation — имя операции контракта Cache, а cache.result у cache.requests принимает значения hit или miss.
Кэши Caffeine не сообщают cache.operation.duration и cache.requests — их телеметрия делегирует стандартным биндерам кэша Micrometer,
которые привязываются к нижележащему кэшу при telemetry.metrics.enabled = true:
| Метрика | Prometheus | Тип | Описание | Теги |
|---|---|---|---|---|
cache.gets |
cache_gets_total |
Counter | Количество обращений к кэшу | cache, result (hit / miss) |
cache.puts |
cache_puts_total |
Counter | Количество записей в кэш | cache |
cache.evictions |
cache_evictions_total |
Counter | Количество вытесненных записей | cache |
cache.eviction.weight |
cache_eviction_weight_total |
Counter | Суммарный вес вытесненных записей | cache |
cache.size |
cache_size |
Gauge | Текущий размер кэша | cache |
Все метрики Caffeine несут тег cache с именем кэша плюс теги из telemetry.metrics.tags.
Kora строит обычный (не загружающий) кэш Caffeine, поэтому метрики загрузки биндера cache.load и cache.load.duration не регистрируются.
Подробнее смотрите в документации модуля Кэш.
Redis / Lettuce¶
| Метрика | Prometheus | Тип | Описание | Теги |
|---|---|---|---|---|
db.client.operation.duration |
db_client_operation_duration_seconds / _count / _sum / _bucket / _max |
Timer | Длительность завершения команды Redis | db.system.name, db.operation.name, server.address, server.port, lettuce.type, error.type |
lettuce.command.firstresponse.duration |
lettuce_command_firstresponse_duration_seconds / _count / _sum / _bucket / _max |
Timer | Длительность первого ответа на команду Redis | db.system.name, db.operation.name, server.address, server.port, lettuce.type, error.type |
Тег db.system.name равен redis; db.operation.name содержит команду, а lettuce.type различает тип клиента. server.address и server.port определяют узел Redis. В error.type записывается только префикс ошибки Redis (например, ERR или MOVED), чтобы ограничить число значений тега. Таймер завершения использует db.client.operation.duration вместе с другими клиентами БД; фильтруйте его по db.system.name=redis.
Отказоустойчивость¶
| Метрика | Prometheus | Тип | Описание | Теги |
|---|---|---|---|---|
resilient.circuitbreaker.state |
resilient_circuitbreaker_state |
Gauge | Состояние предохранителя (0=CLOSED, 1=HALF_OPEN, 2=OPEN) | resilient.name |
resilient.circuitbreaker.transition |
resilient_circuitbreaker_transition_operations_total |
Counter | Переходы в состояния OPEN и HALF_OPEN |
resilient.name, resilient.state |
resilient.circuitbreaker.call.acquire |
resilient_circuitbreaker_call_acquire_operations_total |
Counter | Вызовы, пропущенные в HALF_OPEN, и вызовы, отклоненные в OPEN |
resilient.name, resilient.state, resilient.status |
resilient.circuitbreaker.call.result |
resilient_circuitbreaker_call_result_operations_total |
Counter | Результаты вызовов, зарегистрированные предохранителем | resilient.name, resilient.state, resilient.status |
resilient.retry.attempts |
resilient_retry_attempts_operations_total |
Counter | Количество повторных попыток | resilient.name |
resilient.retry.exhausted |
resilient_retry_exhausted_operations_total |
Counter | Количество исчерпанных повторов | resilient.name, resilient.reason |
resilient.timeout.exhausted |
resilient_timeout_exhausted_operations_total |
Counter | Количество таймаутов | resilient.name |
resilient.fallback.attempts |
resilient_fallback_attempts_operations_total |
Counter | Количество вызовов резервного варианта | resilient.name, resilient.type |
resilient.ratelimiter.acquire |
resilient_ratelimiter_acquire_operations_total |
Counter | Захваты разрешений ограничителем частоты | resilient.name, resilient.status |
Значения тегов: resilient.status равен PERMITTED / REJECTED / DISABLED у call.acquire и SUCCESS / FAILURE / IGNORED_FAILURE / FALLBACK у call.result;
resilient.reason равен EXHAUSTED_ATTEMPTS или EXHAUSTED_BUDGET; resilient.status ограничителя частоты — acquired или rejected; resilient.type резервного варианта — executed.
Подробнее смотрите в документации модуля Отказоустойчивость.
JMS¶
| Метрика | Prometheus | Тип | Описание | Теги |
|---|---|---|---|---|
messaging.process.duration |
messaging_process_duration_seconds / _count / _sum / _bucket / _max |
Timer | Длительность обработки сообщения JMS | messaging.system, messaging.operation.name, messaging.destination.name, error.type |
Тег messaging.system всегда равен jms.
S3-клиент¶
| Метрика | Prometheus | Тип | Описание | Теги |
|---|---|---|---|---|
rpc.client.call.duration |
rpc_client_call_duration_seconds / _count / _sum / _bucket / _max |
Timer | Длительность операции S3-клиента | rpc.system.name, rpc.method, aws.s3.bucket, error.type, system.config, system.name.simple, system.name.canonical |
Тег rpc.system.name равен s3 для клиента на базе AWS. rpc.method — имя операции S3, а system.config — путь конфигурации клиента.
Подробнее смотрите в документации интеграции с AWS S3.
Camunda 7 BPMN¶
| Метрика | Prometheus | Тип | Описание | Теги |
|---|---|---|---|---|
camunda.engine.delegate.duration |
camunda_engine_delegate_duration_seconds / _count / _sum / _bucket / _max |
Timer | Длительность выполнения Java-делегата Camunda BPMN | camunda.delegate, error.type |
Собственные метрики движка публикуются отдельно и требуют camunda.engine.bpmn.telemetry.metrics.engineMetrics = true.
Подробнее смотрите в документации модуля Camunda 7 BPMN.
Camunda REST¶
| Метрика | Prometheus | Тип | Описание | Теги |
|---|---|---|---|---|
camunda.rest.request.duration |
camunda_rest_request_duration_seconds / _count / _sum / _bucket / _max |
Timer | Длительность запроса Camunda REST |
http.request.method, http.response.status_code, http.route, url.scheme, server.address, http.response.result_code, error.type |
camunda.rest.active_requests |
camunda_rest_active_requests |
Gauge | Количество активных запросов Camunda REST | http.request.method, http.route, url.scheme, server.address |
Подробнее смотрите в документации модуля Camunda 7 REST.
Camunda 8 worker¶
| Метрика | Prometheus | Тип | Описание | Теги |
|---|---|---|---|---|
zeebe.worker.handler.duration |
zeebe_worker_handler_duration_seconds / _count / _sum / _bucket / _max |
Timer | Длительность обработчика задачи Zeebe Worker |
job.name, job.type, error.type |
Клиент Camunda дополнительно публикует в тот же реестр собственные метрики задач воркера с тегом job.type.
Подробнее смотрите в документации модуля Camunda 8 Worker.
Система¶
| Метрика | Prometheus | Тип | Описание | Теги |
|---|---|---|---|---|
kora.up |
kora_up |
Gauge | Индикатор состояния фреймворка (значение = 1) | version |
JVM¶
Стандартные метрики JVM и процесса собираются автоматически биндерами Micrometer, привязанными к реестру при старте.
Они не зависят от настройки telemetry.metrics.enabled какого-либо модуля:
| Метрика | Prometheus | Тип | Описание | Теги |
|---|---|---|---|---|
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.buffer.count |
jvm_buffer_count_buffers |
Gauge | Количество буферов в пуле | id |
jvm.buffer.memory.used |
jvm_buffer_memory_used_bytes |
Gauge | Память, используемая буферами | id |
jvm.buffer.total.capacity |
jvm_buffer_total_capacity_bytes |
Gauge | Суммарная емкость пула буферов | id |
jvm.gc.pause |
jvm_gc_pause_seconds / _count / _sum / _max |
Timer | Длительность паузы GC | gc, action, cause |
jvm.gc.concurrent.phase.time |
jvm_gc_concurrent_phase_time_seconds / _count / _sum / _max |
Timer | Длительность конкурентной фазы GC | 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.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.started |
jvm_threads_started_threads_total |
Counter | Количество запущенных потоков | — |
jvm.threads.states |
jvm_threads_states_threads |
Gauge | Количество потоков по состоянию | state |
jvm.classes.loaded |
jvm_classes_loaded_classes |
Gauge | Количество загруженных в данный момент классов | — |
jvm.classes.loaded.count |
jvm_classes_loaded_count_classes_total |
Counter | Количество классов, загруженных с момента старта | — |
jvm.classes.unloaded |
jvm_classes_unloaded_classes_total |
Counter | Количество выгруженных классов | — |
process.cpu.usage |
process_cpu_usage |
Gauge | Использование CPU процессом | — |
system.cpu.usage |
system_cpu_usage |
Gauge | Использование CPU системой | — |
system.cpu.count |
system_cpu_count |
Gauge | Количество доступных процессоров | — |
system.load.average.1m |
system_load_average_1m |
Gauge | Средняя загрузка системы за одну минуту | — |
process.files.open |
process_files_open_files |
Gauge | Количество открытых файловых дескрипторов | — |
process.files.max |
process_files_max_files |
Gauge | Максимальное количество файловых дескрипторов | — |
process.uptime |
process_uptime_seconds |
Gauge | Время работы процесса | — |
process.start.time |
process_start_time_seconds |
Gauge | Время старта процесса от начала эпохи Unix | — |
Часть из них регистрируется только тогда, когда запущенная JVM и операционная система предоставляют соответствующее значение MXBean, поэтому точный набор серий в одном опросе зависит от платформы.