Сбор кастомных JMX-метрик в Proto Observability
На этой странице:
- Введение
- Выбор способа сбора
- Способ 1: сбор через Java-трейсер
- Способ 2: сбор через ProtoOBP Агент
- Синтаксис описания метрик (
conf) - Имена метрик в интерфейсе Proto OBP
- Ограничение на количество метрик
- Проверка и диагностика
Введение
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-трейсер
Предварительные требования
- К приложению подключён Java-трейсер ProtoOBP.
- Сбор JMX-метрик в трейсере включён (включён по умолчанию, см.
POBP_JMXFETCH_ENABLED). - Трейсер может отправлять метрики агенту по протоколу 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
jvm_direct
Instance безjvm_direct: true трейсер пропустит, записав в лог
Skipping instance ... targetDirectInstances=true != jvm_direct=false.
Параметры host, port, user, password в этом режиме не используются.Подключение файла к трейсеру
К параметрам запуска приложения добавьте каталог с конфигурациями и список файлов в нём:
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.
Обратите внимание
Собственная конфигурация не отменяет сбор стандартных метрик JVM и метрик поддерживаемых интеграций (Tomcat, Kafka, Cassandra и др.) — она добавляется к ним.Пример: 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.enabled | POBP_JMXFETCH_ENABLED | true | Включение сбора JMX-метрик |
pobp.jmxfetch.config.dir | POBP_JMXFETCH_CONFIG_DIR | — | Каталог с YAML-файлами конфигураций |
pobp.jmxfetch.config | POBP_JMXFETCH_CONFIG | — | Список файлов конфигураций (через запятую) |
pobp.jmxfetch.check-period | POBP_JMXFETCH_CHECK_PERIOD | 15000 | Период сбора метрик, мс |
pobp.jmxfetch.refresh-beans-period | POBP_JMXFETCH_REFRESH_BEANS_PERIOD | 600 | Период обновления списка подходящих MBean’ов, с |
pobp.jmxfetch.initial-refresh-beans-period | POBP_JMXFETCH_INITIAL_REFRESH_BEANS_PERIOD | — | Период обновления списка bean’ов сразу после старта, с (полезно, если bean’ы регистрируются с задержкой) |
pobp.jmxfetch.start-delay | POBP_JMXFETCH_START_DELAY | 15 | Задержка перед первым сбором, с |
pobp.jmxfetch.statsd.host | POBP_JMXFETCH_STATSD_HOST | адрес агента | Хост, куда отправляются метрики |
pobp.jmxfetch.statsd.port | POBP_JMXFETCH_STATSD_PORT | 8125 | Порт DogStatsD агента |
pobp.trace.jmx.tags | POBP_TRACE_JMX_TAGS | — | Дополнительные лейблы на всех JMX-метриках, формат key1:value1,key2:value2 |
Способ 2: сбор через ProtoOBP Агент
В этом режиме агент подключается к JVM по JMX Remote и опрашивает MBean’ы снаружи. Приложению трейсер не требуется.
Образ агента для JMX
Если ProtoOBP Агент работает в контейнере (Docker, Kubernetes), используйте образ с суффиксом-jmx, например protoobp-agent:7.80.2-jmx. Без этого
суффикса в образе нет JRE и JMX-проверка не запускается.Включение 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=<имя_хоста_или_адрес_интерфейса>
`java.rmi.server.hostname`
JMX RMI отдаёт клиенту адрес второго сокета через значение
java.rmi.server.hostname. Этот адрес должен резолвиться и быть достижим с
хоста (или из контейнера) агента. Не указывайте 0.0.0.0 или localhost —
агент получит этот адрес и упадёт с Connection refused.
На проде включайте аутентификацию JMX
(-Dcom.sun.management.jmxremote.authenticate=true с файлами password/access)
и TLS вместо ssl=false.
Конфигурация проверки на агенте
Создайте файл /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
`collect_default_metrics` и `collect_default_jvm_metrics`
Это два разных параметра:
collect_default_metrics: trueвinit_config— просит агента добавить к проверке готовый набор метрик встроенной интеграции (файлmetrics.yamlрядом сconf.yaml). Работает только для имён встроенных интеграций (tomcat,kafka,activemq,weblogic,cassandraи др.). Для проверки с произвольным именем набора нет — в логе агента появится<имя> doesn't have an additional metric configuration file.collect_default_jvm_metricsна уровне instance — сбор стандартных метрик JVM (heap, GC, потоки). Включён по умолчанию.
Если агент запускается в виде 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_options | JVM-опции сборщика метрик, например -Xmx200m -Xms50m |
trust_store_path, trust_store_password | TrustStore, если на JMX включён SSL |
key_store_path, key_store_password | KeyStore, если на целевой 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.*'
Экранирование в regex
bean_regex — это Java-регулярное выражение, точка в нём означает «любой
символ». Точки в именах доменов и bean’ов экранируйте: com\.example\.app.
Выражения заключайте в одинарные кавычки, чтобы YAML не интерпретировал
обратные слэши.Описание атрибутов и типы метрик
Атрибуты задаются словарём имя_атрибута: {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=Memory →
HeapMemoryUsage) можно обращаться к вложенным полям:
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).