Giter Site home page Giter Site logo

kolesnikovm / jmeter-prometheus-listener Goto Github PK

View Code? Open in Web Editor NEW
20.0 3.0 5.0 12.37 MB

Apache JMeter Backend Listener implementation for Prometheus metrics exporting

License: Apache License 2.0

Java 100.00%
jmeter prometheus jmeter-plugin jmeter-listener jmeter-expoter

jmeter-prometheus-listener's Introduction

Prometheus Listener for JMeter

Apache JMeter Backend Listener implementation for Prometheus metrics exporting. Both pull-based and push-based models are supported through different implementations.

Installation

Download the latest release or build your own from the source code. Then put jmeter-prometheus-listener-x.x.x.jar to JMETER_HOME/lib/ext directory.

Usage

  1. Add Listener->Backend Listener to your Test Plan.
  2. In the Backend Listener implementation combobox select com.github.kolesnikovm.PrometheusListener for pull-based model or com.github.kolesnikovm.PrometheusPusher for push-based one.
  3. Edit parameters to your taste.

Parameters

These parameters are set in Backend Listener element. All parameters are required. You can also add custom parameters, that will be treated as labels and added to each metric.

Param Type Description
testName String Common label for all metrics in your test
runId String Common label for all metrics in your test
exporterPort int Port for exposing metrics, path /metrics
Only for com.github.kolesnikovm.PrometheusListener implementation
prometheusURL String Prometheus URL for pushing metrics
Only for com.github.kolesnikovm.PrometheusPusher implementation
samplersRegExp String Regular expression for filtering sample results
sloLevels String Buckets for jmeter_response_time_histogram. Semicolon delimited

Properties

Property Default Comment
prometheus.collect_jvm false Boolean parameter for enabling JVM metrics collection
prometheus.collect_assertions false Boolean parameter for enabling assertion results collection
prometheus.quantiles_age 10 Max age in seconds for Summary collectors' quantiles
prometheus.log_errors false Boolean parameter for enabling extended error logging
prometheus.push_interval 5 Metrics push interval for com.github.kolesnikovm.PrometheusPusher implementation

Metrics

Every metric has default label set testName, runId, nodeName and also may have some additional labels. Check the table below for details on metrics and their specific labels.

Metric Type Labels Comment
jmeter_active_threads Gauge
jmeter_running_threads Gauge threadGroup
jmeter_requests Counter requestName, requestStatus, responseCode, responseMessage, isTransaction
jmeter_response_time Summary requestName, requestStatus, responseCode, responseMessage, isTransaction Unit: milliseconds
Quantiles: 0.9, 0.95, 0.99
jmeter_response_time_histogram Histogram requestName, requestStatus, responseCode, responseMessage, isTransaction Unit: milliseconds
jmeter_latency Summary requestName, requestStatus, responseCode, responseMessage, isTransaction Unit: milliseconds
Quantiles: 0.9, 0.95, 0.99
jmeter_request_size Summary requestName, requestDirection, isTransaction Unit: bytes
jmeter_assertion_results Counter requestName, failureMessage

Custom metrics

Also, you can create your own custom collectors. See the documentation on Prometheus JVM Client.

Creation

Custom collector creation

Usage

Custom collector usage

Dependency

Plugin is hosted on Maven Central. You can find dependency here. Example use with jmeter-maven-plugin:

<jmeterExtensions>
    <artifact>io.github.kolesnikovm:jmeter-prometheus-listener:x.x.x</artifact>
</jmeterExtensions>

Building

To build, simply run:

gradle clean fatJar

jmeter-prometheus-listener's People

Contributors

kolesnikovm avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

jmeter-prometheus-listener's Issues

Добавления токена авторизации

Добрый день, Спасибо за вашу работу!
Очень хотели бы использовать вашу версию listener`a.
Есть ли возможность добавления в значения параметров, строки для авторизации по токену, как пример:
Authorization: Bearer <token>?

Missing Metrics in both pull and push based models

Hi, I have used this listener to trigger a simple test locally and see the performance metrics as described in the docs, but I have found only one metric (which is jmeter_active_threads) in prometheus in both pull and push based models, rest of the metrics are missing.

Prometheus graphs for remote write -

Screenshot 2024-04-25 at 4 03 27 PM

Metrics Explorer in Prometheus dashboard -

Screenshot 2024-04-25 at 4 05 16 PM

For pull based model I got the following,

Screenshot 2024-04-25 at 4 07 26 PM

Jmeter configurations,

Thread Group,

Screenshot 2024-04-25 at 4 11 18 PM

HTTP Request,

Screenshot 2024-04-25 at 4 08 49 PM

Backend listener,

Screenshot 2024-04-25 at 4 09 47 PM

Jmeter logs,

Screenshot 2024-04-25 at 4 12 56 PM

Versions:

prometheus version (image : prom/prometheus:v2.37.7), macOS sonoma v14.4, docker version - v25.0.3 build 4debf41

JMX file:

<?xml version="1.0" encoding="UTF-8"?>
<jmeterTestPlan version="1.2" properties="5.0" jmeter="5.6.3">
  <hashTree>
    <TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Demotestplan">
      <elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables">
        <collectionProp name="Arguments.arguments"/>
      </elementProp>
      <boolProp name="TestPlan.functional_mode">false</boolProp>
      <boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
    </TestPlan>
    <hashTree>
      <ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Users">
        <intProp name="ThreadGroup.num_threads">1</intProp>
        <intProp name="ThreadGroup.ramp_time">1</intProp>
        <longProp name="ThreadGroup.duration">300</longProp>
        <boolProp name="ThreadGroup.same_user_on_next_iteration">true</boolProp>
        <boolProp name="ThreadGroup.scheduler">true</boolProp>
        <stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
        <elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller">
          <intProp name="LoopController.loops">-1</intProp>
          <boolProp name="LoopController.continue_forever">false</boolProp>
        </elementProp>
      </ThreadGroup>
      <hashTree>
        <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="HTTP Request">
          <stringProp name="HTTPSampler.domain">localhost</stringProp>
          <stringProp name="HTTPSampler.port">8080</stringProp>
          <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
          <stringProp name="HTTPSampler.method">GET</stringProp>
          <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
          <boolProp name="HTTPSampler.postBodyRaw">false</boolProp>
          <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables">
            <collectionProp name="Arguments.arguments"/>
          </elementProp>
        </HTTPSamplerProxy>
        <hashTree/>
        <BackendListener guiclass="BackendListenerGui" testclass="BackendListener" testname="Backend Listener">
          <elementProp name="arguments" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments">
            <collectionProp name="Arguments.arguments">
              <elementProp name="testName" elementType="Argument">
                <stringProp name="Argument.name">testName</stringProp>
                <stringProp name="Argument.value">project</stringProp>
                <stringProp name="Argument.metadata">=</stringProp>
              </elementProp>
              <elementProp name="runId" elementType="Argument">
                <stringProp name="Argument.name">runId</stringProp>
                <stringProp name="Argument.value">1</stringProp>
                <stringProp name="Argument.metadata">=</stringProp>
              </elementProp>
              <elementProp name="prometheusURL" elementType="Argument">
                <stringProp name="Argument.name">prometheusURL</stringProp>
                <stringProp name="Argument.value">http://localhost:9090/api/v1/write</stringProp>
                <stringProp name="Argument.metadata">=</stringProp>
              </elementProp>
              <elementProp name="samplersRegExp" elementType="Argument">
                <stringProp name="Argument.name">samplersRegExp</stringProp>
                <stringProp name="Argument.value">UC.+</stringProp>
                <stringProp name="Argument.metadata">=</stringProp>
              </elementProp>
              <elementProp name="sloLevels" elementType="Argument">
                <stringProp name="Argument.name">sloLevels</stringProp>
                <stringProp name="Argument.value">0.1;1</stringProp>
                <stringProp name="Argument.metadata">=</stringProp>
              </elementProp>
            </collectionProp>
          </elementProp>
          <stringProp name="classname">com.github.kolesnikovm.PrometheusPusher</stringProp>
          <stringProp name="QUEUE_SIZE">100</stringProp>
        </BackendListener>
        <hashTree/>
        <ResultCollector guiclass="TableVisualizer" testclass="ResultCollector" testname="View Results in Table">
          <boolProp name="ResultCollector.error_logging">false</boolProp>
          <objProp>
            <name>saveConfig</name>
            <value class="SampleSaveConfiguration">
              <time>true</time>
              <latency>true</latency>
              <timestamp>true</timestamp>
              <success>true</success>
              <label>true</label>
              <code>true</code>
              <message>true</message>
              <threadName>true</threadName>
              <dataType>true</dataType>
              <encoding>false</encoding>
              <assertions>true</assertions>
              <subresults>true</subresults>
              <responseData>false</responseData>
              <samplerData>false</samplerData>
              <xml>false</xml>
              <fieldNames>true</fieldNames>
              <responseHeaders>false</responseHeaders>
              <requestHeaders>false</requestHeaders>
              <responseDataOnError>false</responseDataOnError>
              <saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
              <assertionsResultsToSave>0</assertionsResultsToSave>
              <bytes>true</bytes>
              <sentBytes>true</sentBytes>
              <url>true</url>
              <threadCounts>true</threadCounts>
              <idleTime>true</idleTime>
              <connectTime>true</connectTime>
            </value>
          </objProp>
          <stringProp name="filename"></stringProp>
        </ResultCollector>
        <hashTree/>
        <ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="View Results Tree">
          <boolProp name="ResultCollector.error_logging">false</boolProp>
          <objProp>
            <name>saveConfig</name>
            <value class="SampleSaveConfiguration">
              <time>true</time>
              <latency>true</latency>
              <timestamp>true</timestamp>
              <success>true</success>
              <label>true</label>
              <code>true</code>
              <message>true</message>
              <threadName>true</threadName>
              <dataType>true</dataType>
              <encoding>false</encoding>
              <assertions>true</assertions>
              <subresults>true</subresults>
              <responseData>false</responseData>
              <samplerData>false</samplerData>
              <xml>false</xml>
              <fieldNames>true</fieldNames>
              <responseHeaders>false</responseHeaders>
              <requestHeaders>false</requestHeaders>
              <responseDataOnError>false</responseDataOnError>
              <saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
              <assertionsResultsToSave>0</assertionsResultsToSave>
              <bytes>true</bytes>
              <sentBytes>true</sentBytes>
              <url>true</url>
              <threadCounts>true</threadCounts>
              <idleTime>true</idleTime>
              <connectTime>true</connectTime>
            </value>
          </objProp>
          <stringProp name="filename"></stringProp>
        </ResultCollector>
        <hashTree/>
        <ResultCollector guiclass="RespTimeGraphVisualizer" testclass="ResultCollector" testname="Response Time Graph">
          <boolProp name="ResultCollector.error_logging">false</boolProp>
          <objProp>
            <name>saveConfig</name>
            <value class="SampleSaveConfiguration">
              <time>true</time>
              <latency>true</latency>
              <timestamp>true</timestamp>
              <success>true</success>
              <label>true</label>
              <code>true</code>
              <message>true</message>
              <threadName>true</threadName>
              <dataType>true</dataType>
              <encoding>false</encoding>
              <assertions>true</assertions>
              <subresults>true</subresults>
              <responseData>false</responseData>
              <samplerData>false</samplerData>
              <xml>false</xml>
              <fieldNames>true</fieldNames>
              <responseHeaders>false</responseHeaders>
              <requestHeaders>false</requestHeaders>
              <responseDataOnError>false</responseDataOnError>
              <saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
              <assertionsResultsToSave>0</assertionsResultsToSave>
              <bytes>true</bytes>
              <sentBytes>true</sentBytes>
              <url>true</url>
              <threadCounts>true</threadCounts>
              <idleTime>true</idleTime>
              <connectTime>true</connectTime>
            </value>
          </objProp>
          <stringProp name="filename"></stringProp>
          <stringProp name="RespTimeGraph.interval">1000</stringProp>
        </ResultCollector>
        <hashTree/>
      </hashTree>
    </hashTree>
  </hashTree>
</jmeterTestPlan>

使用PrometheusListener插件没有数据

我使用的jmeter5.4.2版本,插件jmeter-prometheus-listener-2.6.3.jar,使用默认的PrometheusListener插件,在http://0.0.0.0:9270/metrics页面,没有看到数据,只有如下数据,我是否操作有误

HELP jmeter_active_threads Counter for active threads

TYPE jmeter_active_threads gauge

jmeter_active_threads{nodeName="zhenghuimeng.local",runId="1",testName="project",} 1.0

HELP jmeter_assertion_results Counter for assertion results

TYPE jmeter_assertion_results counter

HELP jmeter_latency Summary for sample ttfb in ms

TYPE jmeter_latency summary

HELP jmeter_response_time_histogram Histogram for sample duration in ms

TYPE jmeter_response_time_histogram histogram

HELP jmeter_response_time Summary for sample duration in ms

TYPE jmeter_response_time summary

HELP jmeter_request_size Summary for jmeter request size in bytes

TYPE jmeter_request_size summary

HELP jmeter_requests Counter for requests

TYPE jmeter_requests counter

HELP jmeter_running_threads Counter for running threads

TYPE jmeter_running_threads gauge

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.