Skip to main content
Back to blog
tutorials 19 September 2023 5 min read

Integrating JMeter with Prometheus and Grafana

Set up real-time JMeter metrics visualization using Prometheus and Grafana for better load test monitoring and analysis.

M

Mark

Performance Testing Expert

JMeter’s built-in reporting is useful but limited for real-time monitoring during test execution. By integrating with Prometheus and Grafana, you get live dashboards, alerting capabilities, and the ability to correlate load test metrics with application infrastructure metrics.

Architecture Overview

The integration works as follows:

JMeter → Prometheus Remote Write → Prometheus Server → Grafana Dashboard

JMeter uses a Backend Listener to push metrics in Prometheus format, which Prometheus scrapes and Grafana visualises.

Setting Up Prometheus

Install Prometheus locally or use Docker:

# docker-compose.yml
version: '3'
services:
  prometheus:
    image: prom/prometheus:latest
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--web.enable-remote-write-receiver'

  grafana:
    image: grafana/grafana:latest
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin
    volumes:
      - grafana-data:/var/lib/grafana

volumes:
  grafana-data:

Configure Prometheus to accept remote writes:

# prometheus.yml
global:
  scrape_interval: 15s

remote_write:
  - url: "http://localhost:9090/api/v1/write"

Start the services:

docker-compose up -d

JMeter Prometheus Backend Listener

Install the Prometheus Listener plugin. Download from JMeter Plugins Manager or manually:

wget https://repo1.maven.org/maven2/com/github/johrstrom/jmeter-prometheus-plugin/0.6.0/jmeter-prometheus-plugin-0.6.0.jar \
  -O $JMETER_HOME/lib/ext/jmeter-prometheus-plugin-0.6.0.jar

Add the Backend Listener to your test plan:

  1. Right-click Test Plan → Add → Listener → Backend Listener
  2. Select com.github.johrstrom.listener.PrometheusListener as Backend Listener implementation

Configure the listener:

PropertyValue
prometheus.save.threadstrue
prometheus.save.jvmtrue
prometheus.port9270

Alternative: Prometheus Remote Write

For direct push to Prometheus without exposing a port:

<!-- In your JMeter test plan -->
<BackendListener guiclass="BackendListenerGui" testclass="BackendListener" testname="Prometheus Backend Listener">
  <elementProp name="arguments" elementType="Arguments">
    <collectionProp name="Arguments.arguments">
      <elementProp name="prometheus.remote.url" elementType="Argument">
        <stringProp name="Argument.name">prometheus.remote.url</stringProp>
        <stringProp name="Argument.value">http://localhost:9090/api/v1/write</stringProp>
      </elementProp>
    </collectionProp>
  </elementProp>
</BackendListener>

Available Metrics

The plugin exposes several metrics:

MetricTypeDescription
jmeter_running_threadsGaugeCurrent active threads
jmeter_requests_totalCounterTotal requests made
jmeter_response_time_secondsHistogramResponse time distribution
jmeter_failures_totalCounterFailed requests
jmeter_success_totalCounterSuccessful requests
jmeter_sent_bytes_totalCounterBytes sent
jmeter_received_bytes_totalCounterBytes received

Labels include:

  • sampler - The sampler name
  • code - HTTP response code
  • success - true/false

Grafana Dashboard Setup

  1. Access Grafana at http://localhost:3000 (admin/admin)
  2. Add Prometheus data source: Configuration → Data Sources → Add → Prometheus
  3. Set URL to http://prometheus:9090 (or http://localhost:9090 if not using Docker network)
  4. Create a new dashboard

Essential Panels

Request Rate:

sum(rate(jmeter_requests_total[1m])) by (sampler)

Response Time Percentiles:

histogram_quantile(0.95, sum(rate(jmeter_response_time_seconds_bucket[1m])) by (le, sampler))

Error Rate:

sum(rate(jmeter_failures_total[1m])) / sum(rate(jmeter_requests_total[1m])) * 100

Active Threads:

jmeter_running_threads

Throughput by Sampler:

sum(rate(jmeter_requests_total[1m])) by (sampler)

Complete Dashboard JSON

Import this dashboard configuration:

{
  "title": "JMeter Load Test",
  "panels": [
    {
      "title": "Requests per Second",
      "type": "timeseries",
      "targets": [{
        "expr": "sum(rate(jmeter_requests_total[1m])) by (sampler)",
        "legendFormat": "{{sampler}}"
      }],
      "gridPos": {"x": 0, "y": 0, "w": 12, "h": 8}
    },
    {
      "title": "Response Time (p95)",
      "type": "timeseries",
      "targets": [{
        "expr": "histogram_quantile(0.95, sum(rate(jmeter_response_time_seconds_bucket[1m])) by (le, sampler))",
        "legendFormat": "{{sampler}}"
      }],
      "gridPos": {"x": 12, "y": 0, "w": 12, "h": 8}
    },
    {
      "title": "Active Threads",
      "type": "gauge",
      "targets": [{
        "expr": "jmeter_running_threads"
      }],
      "gridPos": {"x": 0, "y": 8, "w": 6, "h": 4}
    },
    {
      "title": "Error Rate %",
      "type": "stat",
      "targets": [{
        "expr": "sum(rate(jmeter_failures_total[1m])) / sum(rate(jmeter_requests_total[1m])) * 100"
      }],
      "gridPos": {"x": 6, "y": 8, "w": 6, "h": 4}
    }
  ]
}

Alerting on Performance Issues

Set up Grafana alerts for automatic notification:

# Alert rule for high response time
apiVersion: 1
groups:
  - name: jmeter-alerts
    rules:
      - alert: HighResponseTime
        expr: histogram_quantile(0.95, sum(rate(jmeter_response_time_seconds_bucket[5m])) by (le)) > 2
        for: 2m
        labels:
          severity: warning
        annotations:
          summary: "High response time detected"
          description: "95th percentile response time is above 2 seconds"

      - alert: HighErrorRate
        expr: sum(rate(jmeter_failures_total[5m])) / sum(rate(jmeter_requests_total[5m])) > 0.05
        for: 1m
        labels:
          severity: critical
        annotations:
          summary: "High error rate detected"
          description: "Error rate is above 5%"

Correlating with Application Metrics

The real power comes from viewing JMeter metrics alongside application metrics. If your application already exports Prometheus metrics:

# JMeter throughput vs Application CPU
jmeter_requests_total alongside node_cpu_seconds_total

# Response time vs Database connections
jmeter_response_time_seconds alongside pg_stat_activity_count

Create a combined dashboard with:

  • Top row: JMeter load metrics
  • Middle row: Application metrics (CPU, memory, connections)
  • Bottom row: Infrastructure metrics (database, cache)

Running Tests with Prometheus Integration

Non-GUI mode with Prometheus listener:

jmeter -n -t test-plan.jmx -l results.jtl \
  -Jprometheus.port=9270 \
  -Jprometheus.save.threads=true

The metrics endpoint will be available at http://localhost:9270/metrics for Prometheus to scrape.

Docker-Based Test Execution

For containerised testing:

version: '3'
services:
  jmeter:
    image: justb4/jmeter:latest
    volumes:
      - ./tests:/tests
      - ./results:/results
    command: -n -t /tests/load-test.jmx -l /results/results.jtl
    ports:
      - "9270:9270"
    networks:
      - monitoring

  prometheus:
    image: prom/prometheus:latest
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
    ports:
      - "9090:9090"
    networks:
      - monitoring

  grafana:
    image: grafana/grafana:latest
    ports:
      - "3000:3000"
    networks:
      - monitoring

networks:
  monitoring:

Configure Prometheus to scrape JMeter:

# prometheus.yml
scrape_configs:
  - job_name: 'jmeter'
    static_configs:
      - targets: ['jmeter:9270']

Advantages Over Built-In Reporting

FeatureBuilt-in HTML ReportPrometheus + Grafana
Real-timeNo (post-test)Yes
Custom dashboardsLimitedFully customisable
AlertingNoYes
Correlation with other metricsNoYes
Historical comparisonManualBuilt-in
Team visibilityShare filesShared dashboards

The Prometheus and Grafana integration transforms JMeter from a command-line tool into a real-time monitoring solution. This visibility is invaluable when running long soak tests or when you need to correlate load test results with infrastructure behaviour.

Tags:

#jmeter #prometheus #grafana #monitoring

Need help with performance testing?

Let's discuss how I can help improve your application's performance.

Get in Touch