Search
Write a publication
Pull to refresh

Настройка связки JMeter+Prometheus+Grafana

Доброго времени суток, дорогой читатель!

В данной статье мы с вами постараемся подробно разобраться в настройке плагина Prometheus listener, джобы Prometheus и дашборда в Grafana.

Приступим.

Настройка JMeter

Чтобы наш JMeter отдавал необходимые метрики нам нужен следующий плагин:

https://jmeter-plugins.org/files/packages/jmeter-prometheus-0.6.0.zip

После скачивания подкладываем jmeter-prometheus-plugin-0.6.0.jar в apache-jmeter/lib/ext

Если jmeter был открыт - перезагружаем его.

Создадим простой проект для проверки работоспособности нашей схемы:

Я использую FFA катушку. Если вам удобно пользоваться другой - пользуйтесь другой.

Итак, создадим запрос на yandex.ru:

Добавим View Result Tree, чтобы проверить работу нашего запроса:

Попробуем запустить тест:

Отлично! Наш запрос работает. 

Теперь добавим Prometheus listener:

С помощью кнопки Add добавляем столько строчек, сколько вам нужно. Советую заполнить идентично данному примеру:

Name

Help

Labels

Type

Buckets or Quantiles

Listen to

Measuring   

jmeter_rt_summary

response time summary

category,label,code

SUMMARY

0.75,0.5|0.95,0.1|0.99,0.01

samples

ResponseTime

jmeter_count_total

all code and count

label,code

COUNTER

 

samples

CountTotal

jmeter_success_total

success total

label,code

COUNTER

 

samples

SuccessTotal

jmeter_success_ratio

success ratio

label,code

SUCCESS_RATIO

 

samples

SuccessRatio

jmeter_idle_time

idle time

 

SUMMARY

0.75,0.5|0.95,0.1|0.99,0.01

samples

IdleTime

jmeter_failure_total

failure total

label

COUNTER

 

samples

FailureTotal

jmeter_rt_counter

response time counter

 

SUMMARY

0.75,0.5|0.95,0.1|0.99,0.01

samples

ResponseTime

jmeter_latency_summary

latency summary

 

SUMMARY

0.75,0.5|0.95,0.1|0.99,0.01

samples

Latency

jmeter_connect_time

connect time

 

SUMMARY

0.75,0.5|0.95,0.1|0.99,0.01

samples

ConnectTime  

Итак, листенер настроен. Сохраняем наш тест-план и закрываем jmeter.

Теперь нам нужно отредактировать следующий файл: apache-jmeter/bin/jmeter.properties

Добавить в конец файла строчки:

prometheus.port = 9270
prometheus.ip = 0.0.0.0
#prometheus.delay = 0
prometheus.save.threads = true
prometheus.save.threads.name = jmeter_threads
prometheus.save.jvm = true


Должно получиться следующее:

Перезагружаем jmeter. Открываем план, который мы сделали до этого. Запускаем тест.

Теперь по ссылке <jmeter_ip>:9270/metrics (в моем случае это http://localhost:9270/metrics) jmeter отдает нам наши метрики. Для проверки проходим по этом адресу и нажимаем Ctrl+f. В поиске вставляем название метрики:


It's alive! Alive! Поздравляю, у нас получилось!

Настройка Prometheus

Далее нам нужно создать в Prometheus джобу, которая будет следить за нашим эндпоинтом.

Открываем prometheus.yml и прописываем нашу джобу:

 scrape_configs:
   - job_name: 'jmeter'
     scrape_interval: 5s
     static_configs:
        - targets: ['<jmeter_ip>:9270']

   

Сохраняем файл, перезапускаем Prometheus.

После запуска идем на графический интерфейс прометея:

<prometheus_ip>:9090/targets?search=

И видим следующую картину:

State = DOWN. Отставить панику! Все в порядке, он и должен быть не активным. Вспоминаем - jmeter отдает метрики только во время проведения теста =)

А что это значит? Правильно! Самое время запустить тест и обновить страницу. И, вауля:

По техническим причинам я этого продемонстрировать не могу, но если перейти по Endpoint'у - мы увидим наши метрики =) Мы на верном пути.

Дело за малым - настроить дашборд в Grafana.

Что ж, приступим.

Настройка Grafana

Идем по <grafana_ip>:3000 и логинимся в ней. Где взять логин и пароль от нее с нужными правами - это отдельная тема, покрытая вуалью неизвестности. Поэтому оставим ее за скобками.

Итак, мы вошли. Первым делом нам нужно подключить наш прометей к графане. Идем на вкладку Data sources(1) и нажимаем Add data source(2).

У меня уже подключен прометей, поэтому мы сделаем вид, что мы его не видим =)

Мы нажали на кнопку и получили результат:

Что нам нужно? Правильно, Prometheus. Его и выбираем.

В самом простом варианте мы заполняем только адрес нашего прометея. В рамках крупных проектов - эти настройки лежат на плечах специалистов, у которых есть все "явки и пароли", и, собственно, доступ к настройке всего "вот этого".

Вы спросите зачем тогда тут об этом писать? Хмм... Затем. Можно протестировать все это на локальном компьютере. На русскоязычных ресурсах в просторах ворлд-вайд-веба такой подробной инструкции нету и я подумал, что пускай будет хотя бы тут.

Лирическое отступление закончено, продолжим. Заполняем поле URL: <prometheus_ip>:9090

Листаем вниз и нажимаем кнопку Save & Test и радуемся следующей картине:

Датасорс успешно добавлен. Мы красавчики!

Теперь нам нужно создать новый дашбоард:

Далее мы попадаем в этот дашборд и выбираем создание новой панели:

В этой статье я не буду расписывать создание каждой панели в отдельности, настроим одну, а остальные можно будет настроить по аналогии.

Итак, после нажатия на Add a new panel мы видим:

Минимальное, что нам нужно сделать :

  1. Заполнить название панели.

  2. Переключиться на Code

  3. Если нужно выводить не запрос, а несколько - добавить, использую кнопку + Query.

Итак, заполняем:

Названия дашборда и панелей - на вашей совести. Желательно с цензурой и информативно.

Так же если прокрутить настройки чуть ниже - можно поиграть с визуализацией метрик. На любой вкус и цвет. Почти.

Нажимаем кнопочку Apply. Поздравляю! Вы создали панель. Примерно через час копи-паста и размышлений у вас должно получиться что-то подобное:

Вернемся чуточку назад: я не просто так рекомендовал настраивать прометеус листенер как в этом примере. У меня есть небольшой бонус. Настройки каждой панели =)

Вжух:

*******************************************************************************************************************************************************************Name: Jmeter threadssum(jmeter_threads{state="active"})

Name: Success ratiosum(irate(jmeter_success_ratio_total[$__interval]))

Name: Avg successavg((rate(jmeter_rt_summary_sum{code="200"}[$__interval])/(rate(jmeter_rt_summary_count{code="200"}[$__interval])>0)))

Name: Avg fail(avg(rate(jmeter_success_ratio_failure[$__interval]))/avg(rate(jmeter_success_ratio_total[$__interval])))

Name: Virtual Users vs OK/KOA: sum(rate(jmeter_success_ratio_success[$__interval]))B: sum(jmeter_threads{state="active"})C: sum(rate(jmeter_success_ratio_failure[$__interval]))

Name: Total Requests vs OK/KOA: (sum(rate(jmeter_success_ratio_success[$__interval]))/sum(rate(jmeter_success_ratio_total[$__interval])))B: (sum(rate(jmeter_success_ratio_failure[$__interval]))/sum(rate(jmeter_success_ratio_total[$__interval])))C: sum(rate(jmeter_success_ratio_total[$__interval]))

Name: Avg. Response Time vs Virtual UsersA: sum(jmeter_threads{state="active"})B: avg((rate(jmeter_rt_summary_sum{code="200"}[$__interval])/(rate(jmeter_rt_summary_count{code="200"}[$__interval])>0)))

Name: Avg. Response Time vs OK/KOA: sum(rate(jmeter_success_ratio_success[$__interval]))B: avg((rate(jmeter_rt_summary_sum{code="200"}[$__interval])/(rate(jmeter_rt_summary_count{code="200"}[$__interval])>0)))C: sum(rate(jmeter_success_ratio_failure[$__interval]))

Name: OKsum(jmeter_success_ratio_success) by (label)

Name: KOsum(jmeter_success_ratio_failure) by (label)

Name: Avg. response timeavg (rate(jmeter_rt_summary_sum{code=~"1.*|2.*|3.*|4.*|5.*"}[$__interval]) / (rate(jmeter_rt_summary_count{code=~"1.*|2.*|3.*|4.*|5.*"}[$__interval])>0)) by (label)

Name: Pct response timesavg(jmeter_rt_summary{code="200"}) by (quantile)

Name: Request per second totalA: sum(rate(jmeter_success_ratio_success[$__interval]))B: sum(rate(jmeter_success_ratio_failure[$__interval]))

Name: Request per second by labelsum(rate(jmeter_success_ratio_total[$__interval])) by (label)

Name: Request per second by HTTPCodesum by (code) (rate(jmeter_success_ratio_total[$__interval]))

Name: Errors by HTTPCodesum by(code) (rate(jmeter_success_ratio_failure[$__interval]))

Name: Errors by labelsum by (label) (rate(jmeter_success_ratio_failure[$__interval]))

Name: GC % timeA: rate(jvm_gc_collection_seconds_sum{job=~"jmeter"}[1m])B: rate(jvm_gc_collection_seconds_sum{job=~"jmeter"}[$__interval]) / ignoring(gc) group_left rate(process_cpu_seconds_total{job=~"jmeter"}[$__interval])C: rate(jvm_gc_collection_seconds_sum{job=~"jmeter"}[1m]) / rate(jvm_gc_collection_seconds_count{job=~"jmeter"}[1m])

Name: JVM heap - free memory by pool(jvm_memory_pool_bytes_committed {job=~"jmeter"}) - (jvm_memory_pool_bytes_used{job=~"jmeter"})

Name: JVM heap - used memory by pool(jvm_memory_pool_bytes_used{job="jmeter"})

Name: JVM free memory(jvm_memory_bytes_max {job="jmeter"}) - (jvm_memory_bytes_used{job="jmeter"})

*******************************************************************************************************************************************************************

Ну что же, дорогой читатель. Вот и подошло к концу наше веселое путешествие через настройку связки JMeter+Prometheus+Grafana.

Прошу прощения за количество "буковок" и картинок - я старался сделать инструкцию максимально подробной.

Понимаю, что тут есть еще очень много нюансов, но я очень надеюсь, что этот материал кому-то окажется полезным!

Пишу на Хабре впервые, прошу не судить строго.

Если найдете неточность или какие-то ошибки - милости прошу в комментарии. 

Удачи! =) 

Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.