Сбор кастомных JMX-метрик в Proto Observability

Обновлено 21.08.2026
Сбор произвольных метрик из MBean’ов Java-приложения — через Java-трейсер ProtoOBP или через ProtoOBP Агент.

На этой странице:

Введение

Java-приложения публикуют внутреннее состояние через JMX — в виде атрибутов MBean’ов. Помимо стандартных метрик JVM (heap, GC, потоки) Proto Observability Platform может собирать любые атрибуты MBean’ов: размеры очередей, счётчики бизнес-операций, состояние пулов, метрики Micrometer / Dropwizard Metrics, экспортируемые в JMX, и т. д.

Сбор выполняет встроенный сборщик JMX-метрик, который есть и в Java-трейсере ProtoOBP, и в ProtoOBP Агенте. В обоих случаях набор собираемых метрик задаётся YAML-конфигурацией одного и того же формата: списком фильтров по домену, имени bean’а и имени атрибута.

Выбор способа сбора

Через Java-трейсерЧерез Агент
Требуется -javaagent в приложенииданет
Требуется включённый JMX Remote (порт, java.rmi.server.hostname)нет — подключение внутри JVM (jvm_direct)да
Где лежит конфигурация метрикрядом с приложением (образ, ConfigMap, файловая система пода)на хосте агента (conf.d) или в лейблах контейнера
Автоматическая привязка к сервису (service)да, берётся из конфигурации трейсеразадаётся тегами вручную
Подходит для приложений без трейсера (legacy, сторонние JVM)нетда

Рекомендация: если приложение уже инструментировано Java-трейсером ProtoOBP — используйте способ 1: не нужно открывать JMX-порт наружу, а метрики автоматически получают теги сервиса. Способ 2 используйте для JVM без трейсера, а также если конфигурацию метрик удобнее держать централизованно на агенте.

Способ 1: сбор через Java-трейсер

Предварительные требования

  1. К приложению подключён Java-трейсер ProtoOBP.
  2. Сбор JMX-метрик в трейсере включён (включён по умолчанию, см. POBP_JMXFETCH_ENABLED).
  3. Трейсер может отправлять метрики агенту по протоколу DogStatsD (UDP, порт 8125 на агенте). Если агент работает в контейнере, установите на приложении POBP_DOGSTATSD_NON_LOCAL_TRAFFIC=true, а на агенте — откройте порт 8125 (в Kubernetes — как host port).

Файл конфигурации метрик

Создайте каталог (например /etc/protoobp/jmx/) и в нём файл custom-metrics.yaml:

init_config:
  is_jmx: true
  # Современные имена GC-метрик (jvm_gc_minor_collection_count и т. п.)
  new_gc_metrics: true

instances:
    # Обязательно: трейсер собирает метрики только из instance'ов
    # с jvm_direct: true — подключение идёт внутри той же JVM.
  - jvm_direct: true
    name: my_app_custom_metrics
    conf:
      # Размер очереди заказов: com.example.app:type=OrderQueue -> Size
      - include:
          domain: com.example.app
          bean: 'com.example.app:type=OrderQueue'
          attribute:
            Size:
              alias: myapp.orders.queue_size
              metric_type: gauge
            RejectedCount:
              alias: myapp.orders.rejected
              metric_type: monotonic_count

      # Все пулы соединений приложения; имя пула станет лейблом `pool`
      - include:
          domain: com.example.app
          bean_regex: 'com\.example\.app:type=ConnectionPool,pool=.*'
          attribute:
            ActiveConnections:
              alias: myapp.pool.active
              metric_type: gauge
            IdleConnections:
              alias: myapp.pool.idle
              metric_type: gauge

Подключение файла к трейсеру

К параметрам запуска приложения добавьте каталог с конфигурациями и список файлов в нём:

java -javaagent:/path/to/pobp-java-agent.jar \
  -Dpobp.service=my_service_name \
  -Dpobp.jmxfetch.config.dir=/etc/protoobp/jmx \
  -Dpobp.jmxfetch.config=custom-metrics.yaml \
  -jar my_app.jar

То же самое переменными окружения:

export POBP_JMXFETCH_CONFIG_DIR=/etc/protoobp/jmx
export POBP_JMXFETCH_CONFIG=custom-metrics.yaml

В POBP_JMXFETCH_CONFIG можно перечислить несколько файлов через запятую — пути указываются относительно POBP_JMXFETCH_CONFIG_DIR.

Пример: Docker

FROM eclipse-temurin:17-jre
WORKDIR /opt/app

ENV POBP_AGENT_HOST="protoobp-agent"
ENV POBP_SERVICE="my_service_name"
# Необходимо для доставки JMX-метрик агенту в контейнере
ENV POBP_DOGSTATSD_NON_LOCAL_TRAFFIC="true"
# Кастомные JMX-метрики
ENV POBP_JMXFETCH_CONFIG_DIR="/etc/protoobp/jmx"
ENV POBP_JMXFETCH_CONFIG="custom-metrics.yaml"

COPY pobp-java-agent.jar /opt/app/pobp-java-agent.jar
COPY custom-metrics.yaml /etc/protoobp/jmx/custom-metrics.yaml
COPY target/my-app.jar /opt/app/my-app.jar

CMD ["java", "-javaagent:/opt/app/pobp-java-agent.jar", "-jar", "/opt/app/my-app.jar"]

Пример: Kubernetes

Конфигурацию метрик удобно хранить в ConfigMap — тогда для изменения набора метрик не нужно пересобирать образ:

apiVersion: v1
kind: ConfigMap
metadata:
  name: pobp-jmx-config
data:
  custom-metrics.yaml: |
    init_config:
      is_jmx: true
    instances:
      - jvm_direct: true
        name: my_app_custom_metrics
        conf:
          - include:
              domain: com.example.app
              attribute:
                Size:
                  alias: myapp.orders.queue_size
                  metric_type: gauge    
---
apiVersion: apps/v1
kind: Deployment
#(...)
    spec:
      containers:
        - name: my-app
          env:
            - name: POBP_SERVICE
              value: my_service_name
            - name: POBP_AGENT_HOST
              valueFrom:
                fieldRef:
                  fieldPath: status.hostIP
            - name: POBP_DOGSTATSD_NON_LOCAL_TRAFFIC
              value: "true"
            - name: POBP_JMXFETCH_CONFIG_DIR
              value: /etc/protoobp/jmx
            - name: POBP_JMXFETCH_CONFIG
              value: custom-metrics.yaml
          volumeMounts:
            - name: pobp-jmx-config
              mountPath: /etc/protoobp/jmx
      volumes:
        - name: pobp-jmx-config
          configMap:
            name: pobp-jmx-config

Параметры JMX-сбора в трейсере

System PropertyПеременная окруженияПо умолчаниюОписание
pobp.jmxfetch.enabledPOBP_JMXFETCH_ENABLEDtrueВключение сбора JMX-метрик
pobp.jmxfetch.config.dirPOBP_JMXFETCH_CONFIG_DIRКаталог с YAML-файлами конфигураций
pobp.jmxfetch.configPOBP_JMXFETCH_CONFIGСписок файлов конфигураций (через запятую)
pobp.jmxfetch.check-periodPOBP_JMXFETCH_CHECK_PERIOD15000Период сбора метрик, мс
pobp.jmxfetch.refresh-beans-periodPOBP_JMXFETCH_REFRESH_BEANS_PERIOD600Период обновления списка подходящих MBean’ов, с
pobp.jmxfetch.initial-refresh-beans-periodPOBP_JMXFETCH_INITIAL_REFRESH_BEANS_PERIODПериод обновления списка bean’ов сразу после старта, с (полезно, если bean’ы регистрируются с задержкой)
pobp.jmxfetch.start-delayPOBP_JMXFETCH_START_DELAY15Задержка перед первым сбором, с
pobp.jmxfetch.statsd.hostPOBP_JMXFETCH_STATSD_HOSTадрес агентаХост, куда отправляются метрики
pobp.jmxfetch.statsd.portPOBP_JMXFETCH_STATSD_PORT8125Порт DogStatsD агента
pobp.trace.jmx.tagsPOBP_TRACE_JMX_TAGSДополнительные лейблы на всех JMX-метриках, формат key1:value1,key2:value2

Способ 2: сбор через ProtoOBP Агент

В этом режиме агент подключается к JVM по JMX Remote и опрашивает MBean’ы снаружи. Приложению трейсер не требуется.

Включение JMX Remote в приложении

К параметрам запуска JVM добавьте:

-Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.port=9010 \
-Dcom.sun.management.jmxremote.rmi.port=9010 \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false \
-Dcom.sun.management.jmxremote.local.only=false \
-Djava.rmi.server.hostname=<имя_хоста_или_адрес_интерфейса>

Конфигурация проверки на агенте

Создайте файл /etc/protoobp-agent/conf.d/<имя_проверки>.d/conf.yaml, где <имя_проверки> — произвольное имя (например myapp):

init_config:
  is_jmx: true
  new_gc_metrics: true
  # Дополнительные jar'ы в classpath JVM агента, если нужны свои классы
  # custom_jar_paths:
  #   - /opt/protoobp/myapp-jmx-classes.jar

instances:
  - host: localhost
    port: 9010
    name: myapp_instance
    # Собирать стандартные метрики JVM вместе с кастомными (по умолчанию true)
    collect_default_jvm_metrics: true
    # user: monitorRole      # если на JMX включена аутентификация
    # password: <пароль>
    tags:
      - service:my_service_name
      - env:prod
    conf:
      - include:
          domain: com.example.app
          bean: 'com.example.app:type=OrderQueue'
          attribute:
            Size:
              alias: myapp.orders.queue_size
              metric_type: gauge

Перезапустите агента:

systemctl restart protoobp-agent

Если агент запускается в виде Docker контейнера

Набор метрик можно задать autodiscovery-лейблами прямо на контейнере приложения:

services:
  my-app:
    labels:
      com.protoobp.ad.check_names: '["myapp"]'
      com.protoobp.ad.init_configs: '[{"is_jmx": true, "new_gc_metrics": true}]'
      com.protoobp.ad.instances: >-
        [{"host": "%%host%%", "port": "9010", "name": "myapp_instance",
          "conf": [{"include": {"domain": "com.example.app",
                                "attribute": {"Size": {"alias": "myapp.orders.queue_size",
                                                       "metric_type": "gauge"}}}}]}]        

Контейнер агента должен находиться в одной docker network с приложением, иметь образ с суффиксом -jmx и смонтированный /var/run/docker.sock:/var/run/docker.sock:ro для autodiscovery.

Параметры подключения к JVM

ПараметрОписание
host, portАдрес и порт JMX Remote
jmx_urlНестандартный JMX URL вместо host/port, например service:jmx:rmi:///jndi/rmi://host:9999/jmxrmi. При использовании обязательно задайте name
user, passwordУчётные данные JMX
process_name_regexПодключение к локальному процессу через attach API вместо host/port. Требует установленного JDK и tools_jar_path
tools_jar_pathПуть к tools.jar (обязателен вместе с process_name_regex)
nameИмя instance’а — попадает в лейбл instance
tagsСписок лейблов key:value на всех метриках instance’а
refresh_beansПериод обновления списка подходящих MBean’ов, с (по умолчанию 600)
java_bin_pathПуть к java, если агент не может его найти
java_optionsJVM-опции сборщика метрик, например -Xmx200m -Xms50m
trust_store_path, trust_store_passwordTrustStore, если на JMX включён SSL
key_store_path, key_store_passwordKeyStore, если на целевой JVM включена клиентская аутентификация
rmi_registry_sslПодключаться к RMI-реестру по SSL
collect_default_jvm_metricsСбор стандартных метрик JVM (по умолчанию true)
max_returned_metricsЛимит метрик на instance, см. ниже

Синтаксис описания метрик (conf)

Секция conf — список правил. Каждое правило содержит include (что собирать) и, опционально, exclude (что из этого исключить). Формат одинаков для трейсера и для агента.

Фильтры include и exclude

КлючОписание
domainТочное имя JMX-домена, например com.example.app
domain_regexРегулярное выражение по домену
bean (или bean_name)Полное имя MBean’а или список имён
bean_regexРегулярное выражение по полному имени MBean’а или список выражений
classИмя Java-класса MBean’а
attributeОписание собираемых атрибутов (см. ниже). В exclude можно перечислить атрибуты списком
tagsДополнительные лейблы, добавляемые к метрикам правила
exclude_tagsСписок лейблов, которые не нужно добавлять к метрикам
conf:
  # Собрать весь домен, кроме служебных bean'ов
  - include:
      domain: com.example.app
    exclude:
      bean_regex:
        - 'com\.example\.app:type=Internal.*'

Описание атрибутов и типы метрик

Атрибуты задаются словарём имя_атрибута: {alias, metric_type}:

attribute:
  Size:
    alias: myapp.orders.queue_size
    metric_type: gauge
  TotalProcessed:
    alias: myapp.orders.processed
    metric_type: monotonic_count
metric_typeПоведение
gaugeМгновенное значение атрибута (по умолчанию)
rateЗначение монотонного счётчика конвертируется в скорость изменения в секунду
monotonic_countМонотонный счётчик передаётся как приращение между сборами
counterУстаревший синоним rate, использовать не рекомендуется
histogramРаспределение значений (percentiles, avg, max)

Если атрибуты не перечислены явно, будут собраны все числовые атрибуты подходящих bean’ов, а имена метрик составятся автоматически из домена и имени атрибута. Это удобно для разведки, но на большом домене быстро упирается в лимит метрик — в рабочей конфигурации перечисляйте атрибуты и задавайте alias явно.

Лейблы метрик

К JMX-метрикам автоматически добавляются:

ЛейблЗначение
hostХост, на котором работает приложение (способ 1) или агент (способ 2)
instanceЗначение name из конфигурации instance’а
jmx_domainДомен MBean’а
service, envТеги сервиса — из конфигурации трейсера (способ 1) или из tags (способ 2)

Кроме того, все параметры из имени MBean’а становятся лейблами. Например bean com.example.app:type=ConnectionPool,pool=orders даёт лейблы type:ConnectionPool и pool:orders — по ним метрику можно разбивать на графике и фильтровать. Ненужные параметры отключаются через exclude_tags.

Составные атрибуты

Для атрибутов типа CompositeData (например java.lang:type=MemoryHeapMemoryUsage) можно обращаться к вложенным полям:

conf:
  - include:
      domain: com.example.app
      bean: 'com.example.app:type=Cache'
      attribute:
        Stats.hitCount:
          alias: myapp.cache.hits
          metric_type: monotonic_count
        Stats.missCount:
          alias: myapp.cache.misses
          metric_type: monotonic_count

Имена метрик в интерфейсе Proto OBP

Точки в имени метрики (alias) при сохранении заменяются на подчёркивания. Метрика с alias: myapp.orders.queue_size в Metrics Explorer, на дашбордах и в правилах алертов доступна как:

myapp_orders_queue_size

Рекомендации по именованию:

  • используйте общий префикс приложения (myapp., billing.) — так метрики легко найти в Metrics Explorer;
  • не используйте префикс jvm. — он зарезервирован для стандартных метрик JVM;
  • имя должно описывать величину, а разрезы (инстанс, пул, очередь) выносите в лейблы, а не в имя метрики.

Ограничение на количество метрик

Один instance по умолчанию отдаёт не более 350 метрик. При превышении лишние метрики отбрасываются, а в логе появляется предупреждение Maximum number of metrics reached.

Если метрик действительно нужно больше, увеличьте лимит в конфигурации instance’а:

instances:
  - jvm_direct: true
    name: my_app_custom_metrics
    max_returned_metrics: 2000
    conf:
      # ...

Прежде чем поднимать лимит, сузьте фильтры: сбор всего домена без перечисления атрибутов создаёт большое количество ненужных временных рядов и повышает стоимость хранения.

Проверка и диагностика

Способ 1 (трейсер). Запустите приложение с включённым отладочным логом JMX-сборщика:

-Dorg.slf4j.simpleLogger.log.org.datadog.jmxfetch=debug

В логе приложения будет видно, какие файлы конфигураций загружены, какие bean’ы подошли под фильтры и сколько метрик отправлено. Типичные сообщения:

Сообщение в логеПричина
Skipping instance ... jvm_direct=falseВ instance не указан jvm_direct: true
Maximum number of metrics reachedПревышен лимит метрик, см. выше
Нет метрик, ошибок нетФильтр не совпал ни с одним bean’ом — проверьте домен и имя bean’а через jconsole / jmxterm

Способ 2 (агент). Статус проверки:

docker exec protoobp-agent agent status | grep -A 8 "^    myapp$"

Ожидается status : OK и metric_count > 0. Полезные команды:

# Все атрибуты, подошедшие под фильтры и собираемые сейчас
docker exec protoobp-agent agent jmx list collected

# Атрибуты, подошедшие под include, но не собираемые (не числовые и т. п.)
docker exec protoobp-agent agent jmx list matching

# Всё, что доступно в JVM — для поиска нужных bean'ов и атрибутов
docker exec protoobp-agent agent jmx list everything

# Атрибуты, отброшенные из-за лимита max_returned_metrics
docker exec protoobp-agent agent jmx list limited

Итоговая проверка. Метрика должна появиться в разделе Метрики > Metrics Explorer под именем с подчёркиваниями (myapp_orders_queue_size). Первые значения приходят через 15–30 секунд после старта приложения (start-delay + check-period).