WSO2 Micro Integrator - добавление кастомных метрик. Fear and loathing... - WSO2 Micro Integrator - добавление кастомных метрик. Fear and loathing...
Блоги
Навигационные полоски
Для одного из заказчиков недавно возникла необходимость получать кастомные метрики по сервисам WSO2 Micro Integrator - API, Proxy, Inbound Endpoint. Изначально это выглядело вполне реализуемым штатными средствами, но не тут-то было!
Для выведения метрик и оповещений мы используем связку Prometheus и Grafana. У WSO2 для этого есть подготовленные dashboard-ы, что очень удобно.
Пример для прокси сервиса:
Для сбора логов используется Grafana Loki.
Под сбор Prometheus-ом подготавливаются несколько метрик для сервисов.
На примере Proxy стандартно есть 2 счётчика, для остальных сущностей метрики идентичны:
- wso2_integration_proxy_request_count_total — общее количество запросов
- wso2_integration_proxy_request_count_error_total — количество ошибок
гистограмма по задержкам ответа:
- wso2_integration_proxy_latency_seconds
и таймер «Up time»
- wso2_integration_service_up
Сбор метрик на Micro Integrator 4.0.0 (MI) запускается предельно просто: в deployment.toml дописываем:
[[synapse_handlers]]
name="CustomObservabilityHandler" class="org.wso2.micro.integrator.observability.metric.handler.MetricHandler"
и запускаем MI командой
micro-integrator.bat -DenablePrometheusApi=true
Более подробная статья по запуску и настройке мониторинга по ссылке.
Заказчику нужен был сбор метрик по параметрам из тела сообщения...
Сразу возникла мысль:
Вариант 1:
- На входе в сервис разбираем тело сообщения и выводим в лог строки в определённом формате, таким образом любой параметр в кармане.
- Собираем логи упомянутым в статье по мониторингу Grafana Loki.
- Выводим в Grafana, успех!
Но нет.
При формировании dashboard в Grafana с расчётными графиками и гистограммами за большой период получаем большую нагрузку на Loki и, как следствие, большую задержку.
В теории, для этих целей можно использовать более мощный стек ELK(Elasticsearch, Logstash and Kibana), но это дополнительные сервера и последующая их поддержка. Из-за этого вынуждены были всё же отказаться от этой идеи.
Вариант 2:
Так же вполне удобным и простым выглядело расширение метрик для связки Prometheus и Grafana.
Реализация:
Переопределяем упомянутый выше обработчик org.wso2.micro.integrator.observability.metric.handler.MetricHandler и прописываем его в deployment.toml:
[[synapse_handlers]]
name="CustomObservabilityHandler" class="ru.emdev.test.common.CustomMetricHandler"
Ура, но нет...
Это только начало тернистого пути...
Наследуемся от MetricHandler, живущего в бандле org.wso2.micro.integrator.observability_4.0.0, переопределяем метод handleRequestInFlow в котором происходит обработка запросов.
У нас есть MessageContext и доступ к функционалу клиента Prometheus, что ещё для счастья надо?)
Но весь функционал работы с Prometheus находится в org.wso2.micro.integrator.observability.metric.handler.prometheus.reporter.PrometheusReporter, который хранится в приватном поле родителя MetricHandler.
Для получения доступа к полю metricReporterInstance используем Reflection.
К сожалению, в методе для создания метрик PrometheusReporter.createMetrics все метрики заданы жёстко и создаются вне зависимости от переданного названия….
Значит одним MetricHandler тут не отделаться, переопределяем PrometheusReporter!
К счастью, в инициализации MetricHandler была замечены такая строка
Object metricReporterClass = configs.get(MetricConstants.METRIC_HANDLER + "." + METRIC_REPORTER);
т.е. можно легально переопределить данный класс.
Наследуемся от PrometheusReporter, подключаем библиотеки для работы с Prometheus.
Фиксим момент с жёстко заданными метриками типа:
TOTAL_REQUESTS_RECEIVED_PROXY_SERVICE = Counter.build(MetricConstants.PROXY_REQUEST_COUNT_TOTAL, metricHelp).
labelNames(labels).register();
metricMap.put(metricName, TOTAL_REQUESTS_RECEIVED_PROXY_SERVICE);
где при создании счётчика мы используем константу PROXY_REQUEST_COUNT_TOTAL, как наименование, а далее уже складываем в Map используя metricName.
Собираем бандл, подкладываем в папку lib, перезагружаем и получаем не удивительную вещь...
Полностью вытаскивая весь класс PrometheusReporter мы избавляемся от ClassCastException, но упираемся в проблему с разными classloader ещё раз, из-за того, что в реализации клиента Prometheus повсеместно используется static-а. Что наглядно видно при входе в сервис метрик <host>:9201/metric-service/metrics - там просто-напросто пусто, т.к. все метрики в classloader нашего бандла.
Останавливаться нельзя, - только вперёд!!!
Принято решение вытащить бандл org.wso2.micro.integrator.observability полностью.
По сути осталось всего 3 класса:
- MetricAPI
- MetricFormatter
- MetricResource
Упомянутые классы переносим без изменений.
Выставляемое API <host>:9201/metric-service/metrics, которое реализуется в классе MetricAPI, относится к служебным и прописано в конфигурационном файле internal-apis.xml
Прописываем свой класс для PrometheusApi:
<api name="PrometheusApi" protocol="http" class="org.wso2.micro.integrator.observability.metric.publisher.MetricAPI">
После перезагрузки MI начинает отбиваться от инородных захватчиков и восстанавливает файл internal-apis.xml до заводского состояния, а файл с изменениями складывает в папку backup/conf.
Прописываем свой класс ещё раз и MI тут же сдаётся под натиском и перестаёт восстанавливать файл.
В итоге получаем почти полный бандл мониторинга за исключением утильного класса MetricConstants.
- MetricHandler отнаследовались
- PrometheusReporter полностью
- MetricAPI полностью
- MetricFormatter полностью
- MetricResource полностью
Изменили конфигурационные файлы:
- deployment.toml
- internal-apis.xml
Используя это решение мы можем без проблем добавлять метрики для Prometheus, обрабатывая запрос в методе MetricHandler.handleRequestInFlow.
Удачных вам интеграций!
- 6.2 (12)
- 7.0 (12)
- activiti (14)
- apache camel (6)
- camel (11)
- devcon (6)
- devops (5)
- emdev (9)
- emdev limited (9)
- entaxy (13)
- esb (10)
- fuse (5)
- gartner (7)
- google apps (6)
- jboss (5)
- liferay (143)
- liferay 7.1 (11)
- liferay dxp (11)
- liferay7 (12)
- openshift (8)
- osgi (5)
- redhat (15)
- rest (6)
- wso2 (70)
- wso2 api-m (10)
- wso2 ei (8)
- wso2ei (5)
- wso2esb (7)
- wso2is (8)
- емдев (11)
Сайт использует файлы cookie. Они позволяют узнавать вас и получать информацию о вашем пользовательском опыте. Это нужно, чтобы улучшать сайт. Посещая страницы сайта и предоставляя свои данные, вы позволяете нам предоставлять их сторонним партнерам. Если вы согласны, продолжайте пользоваться сайтом. Если нет – установите специальные настройки в браузере или обратитесь в техподдержку.