Перейти к содержанию
V1 V2

Метрики

Модуль для сбора метрик приложения с помощью 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:

implementation "io.koraframework:micrometer-module"

Модуль:

@KoraApp
public interface Application extends MetricsModule { }

Зависимость build.gradle.kts:

implementation("io.koraframework:micrometer-module")

Модуль:

@KoraApp
interface Application : MetricsModule

MetricsModule находится в пакете io.koraframework.micrometer.module. Он предоставляет реестр, общие теги приложения и контракт эндпоинта для опроса — сами значения метрик создают подключенные вами модули (HTTP-сервер, HTTP-клиент, База данных, Kafka и так далее).

Конфигурация

Метрики настраиваются в трех местах: общая для приложения секция metrics модуля MetricsModule, путь и порт эндпоинта опроса на системном сервере, а также блок telemetry.metrics внутри каждого модуля, который сообщает метрики.

Метрики приложения

Секция metrics описывается классом MetricsConfig из пакета io.koraframework.micrometer.module (указаны значения по умолчанию):

metrics {
    enabled = true //(1)!
    tags { //(2)!
        "application" = "example-service"
        "environment" = "stage"
    }
}
  1. Общий переключатель метрик приложения (по умолчанию: true)
  2. Общие теги, добавляемые ко всем метрикам реестра: метрикам модулей, JVM и пользовательским (по умолчанию: {})
metrics:
  enabled: true #(1)!
  tags: #(2)!
    application: "example-service"
    environment: "stage"
  1. Общий переключатель метрик приложения (по умолчанию: true)
  2. Общие теги, добавляемые ко всем метрикам реестра: метрикам модулей, JVM и пользовательским (по умолчанию: {})

При 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:

@Component
public final class HostMetricsTagsProvider implements MetricsTagsProvider {

    @Override
    public Map<String, String> tags() {
        return Map.of("host", System.getenv().getOrDefault("HOSTNAME", "unknown"));
    }
}
@Component
class HostMetricsTagsProvider : MetricsTagsProvider {

    override fun tags(): Map<String, String> {
        return mapOf("host" to (System.getenv("HOSTNAME") ?: "unknown"))
    }
}

Поставщиков можно зарегистрировать сколько угодно. MetricsModule собирает их все, объединяет их теги с metrics.tags и через PrometheusMeterRegistryInitializer устанавливает на реестр один глобальный MeterFilter.commonTags(...). При совпадении ключей значение из metrics.tags побеждает любого поставщика. Теги вычисляются один раз, при создании реестра, поэтому поставщик не должен возвращать значения, зависящие от запроса. Этот инициализатор — обычный компонент, а не @DefaultComponent, поэтому общие теги применяются и тогда, когда приложение объявляет собственные PrometheusMeterRegistryInitializer: инициализатор общих тегов работает вместе с ними, смотрите Персонализация.

Эндпоинт опроса

Пример конфигурации пути системного HTTP-сервера, описанной в классе SystemHttpServerConfig (указаны значения по умолчанию):

httpServer {
    system {
        port = 8085 //(1)!
        metricsPath = "/metrics" //(2)!
    }
}
  1. Порт системного HTTP-сервера, который обслуживает эндпоинт метрик (по умолчанию: 8085).
  2. Путь для получения метрик в формате Prometheus (по умолчанию: "/metrics").
httpServer:
  system:
    port: 8085 #(1)!
    metricsPath: "/metrics" #(2)!
  1. Порт системного HTTP-сервера, который обслуживает эндпоинт метрик (по умолчанию: 8085).
  2. Путь для получения метрик в формате 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"
            }
        }
    }
}
  1. Включает сбор метрик для модуля (по умолчанию: false)
  2. Корзины гистограммы SLO для метрик Timer, список длительностей (по умолчанию: TelemetryConfig.MetricsConfig#DEFAULT_SLO, перечислен в разделе Персонализация)
  3. Дополнительные общие теги, добавляемые к каждой метрике, которую сообщает модуль (по умолчанию: {})
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
  1. Включает сбор метрик для модуля (по умолчанию: false)
  2. Корзины гистограммы SLO для метрик Timer, список длительностей (по умолчанию: TelemetryConfig.MetricsConfig#DEFAULT_SLO, перечислен в разделе Персонализация)
  3. Дополнительные общие теги, добавляемые к каждой метрике, которую сообщает модуль (по умолчанию: {})

Значения 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:

@Component
public final class SomeService {

    private final MeterRegistry meterRegistry;

    public SomeService(MeterRegistry meterRegistry) {
        this.meterRegistry = meterRegistry;
    }
}
@Component
class SomeService(
    private val 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):

curl http://localhost:8085/metrics

Направьте цель опроса вашего 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:

@Module
public interface MetricsScraperModule {

    default MetricsScraper metricsScraper(MeterRegistry registry) {
        return os -> os.write(renderMyFormat(registry).getBytes(StandardCharsets.UTF_8));
    }
}
@Module
interface MetricsScraperModule {

    fun metricsScraper(registry: MeterRegistry): MetricsScraper {
        return MetricsScraper { os -> os.write(renderMyFormat(registry).toByteArray()) }
    }
}

Пользовательская метрика

Для пользовательской метрики лучше создать отдельный компонент, внедрить 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, который отбрасывает ненужные метрики:

@Module
public interface MetricsConfigModule {

    default PrometheusMeterRegistryInitializer denyGcMetricsInit() {
        return registry -> {
            registry.config().meterFilter(MeterFilter.denyNameStartsWith("jvm.gc"));
            return registry;
        };
    }
}
@Module
interface MetricsConfigModule {

    fun denyGcMetricsInit(): PrometheusMeterRegistryInitializer {
        return PrometheusMeterRegistryInitializer {
            it.config().meterFilter(MeterFilter.denyNameStartsWith("jvm.gc"))
            it
        }
    }
}

У стандартных метрик также есть собственные настройки, например корзины гистограммы 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");
        }
    }
}
  1. Фабрику подхватывает HttpServerModule#defaultHttpServerTelemetryFactory вместо встроенной DefaultHttpServerMetricsFactory
  2. В билдере допустимы только статические теги — тег, значение которого меняется от запроса к запросу, должен быть частью ключа метрики, иначе разные наборы тегов схлопнутся в один 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")
        }
    }
}
  1. Фабрику подхватывает HttpServerModule#defaultHttpServerTelemetryFactory вместо встроенной DefaultHttpServerMetricsFactory
  2. В билдере допустимы только статические теги — тег, значение которого меняется от запроса к запросу, должен быть частью ключа метрики, иначе разные наборы тегов схлопнутся в один 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, поэтому точный набор серий в одном опросе зависит от платформы.