Operations 15 min read

How to Visualize JMeter Performance Data with Grafana, InfluxDB, and Prometheus

This article explains step‑by‑step how to collect JMeter test metrics via Backend Listener, store them in InfluxDB, and display real‑time performance charts—including TPS, response time, and error rates—in Grafana, while also covering node_exporter integration with Prometheus for system‑level monitoring.

Efficient Ops
Efficient Ops
Efficient Ops
How to Visualize JMeter Performance Data with Grafana, InfluxDB, and Prometheus

Overview

The article outlines a practical monitoring workflow for performance testing, focusing on the most common components: JMeter, InfluxDB, Grafana, Prometheus, and node_exporter. It explains why raw JMeter console output or HTML reports are insufficient for large‑scale analysis and introduces a data‑driven approach.

JMeter + InfluxDB + Grafana

JMeter’s Backend Listener can send metrics asynchronously to InfluxDB (or Graphite). After configuring the listener, metrics such as total requests, response time, thread count, and error rate are written to InfluxDB every 30 seconds. Grafana then uses an InfluxDB data source and a pre‑built JMeter dashboard (ID 5496) to render real‑time charts that match the console output.

<code>private void addMetrics(String transaction, SamplerMetric metric) {
    // FOR ALL STATUS
    addMetric(transaction, metric.getTotal(), metric.getSentBytes(), metric.getReceivedBytes(), TAG_ALL, metric.getAllMean(), metric.getAllMinTime(),
        metric.getAllMaxTime(), allPercentiles.values(), metric::getAllPercentile);
    // FOR OK STATUS
    addMetric(transaction, metric.getSuccesses(), null, null, TAG_OK, metric.getOkMean(), metric.getOkMinTime(),
        metric.getOkMaxTime(), okPercentiles.values(), metric::getOkPercentile);
    // FOR KO STATUS
    addMetric(transaction, metric.getFailures(), null, null, TAG_KO, metric.getKoMean(), metric.getKoMinTime(),
        metric.getKoMaxTime(), koPercentiles.values(), metric::getKoPercentile);
    metric.getErrors().forEach((error, count) -> addErrorMetric(transaction, error.getResponseCode(),
        error.getResponseMessage(), count));
}</code>
<code>@Override public void writeAndSendMetrics() {
    if (!copyMetrics.isEmpty()) {
        if (httpRequest == null) {
            httpRequest = createRequest(url);
        }
        StringBuilder sb = new StringBuilder(copyMetrics.size()*35);
        for (MetricTuple metric : copyMetrics) {
            sb.append(metric.measurement)
              .append(metric.tag)
              .append(" ")
              .append(metric.field)
              .append(" ")
              .append(metric.timestamp+"000000")
              .append("\n");
        }
        StringEntity entity = new StringEntity(sb.toString(), StandardCharsets.UTF_8);
        httpRequest.setEntity(entity);
        lastRequest = httpClient.execute(httpRequest, new FutureCallback<HttpResponse>() {
            @Override public void completed(final HttpResponse response) {
                int code = response.getStatusLine().getStatusCode();
                if (MetricUtils.isSuccessCode(code)) {
                    if (log.isDebugEnabled()) {
                        log.debug("Success, number of metrics written: {}", copyMetrics.size());
                    }
                } else {
                    log.error("Error writing metrics to influxDB Url: {}, responseCode: {}, responseBody: {}", url, code, getBody(response));
                }
            }
            @Override public void failed(final Exception ex) { log.error("failed to send data to influxDB server : {}", ex.getMessage()); }
            @Override public void cancelled() { log.warn("Request to influxDB server was cancelled"); }
        });
    }
}</code>

These snippets show how JMeter metrics are transformed into InfluxDB line protocol and sent via HTTP.

InfluxDB Storage Structure

Two measurements are created:

events

(test‑level metadata) and

jmeter

(transaction statistics). Queries in Grafana retrieve data from the

jmeter

measurement to plot throughput and percentile response‑time curves.

Grafana Configuration

Configure an InfluxDB data source, import the official JMeter dashboard, and select the appropriate measurement. The dashboard displays total TPS, 95th‑percentile response time, and per‑transaction statistics in real time.

node_exporter + Prometheus + Grafana

For system‑level monitoring, node_exporter exposes OS counters (CPU, memory, disk, etc.) which Prometheus scrapes. After adding a static job for the node_exporter endpoint in

prometheus.yml

, Grafana uses a node_exporter template (ID 11074) to visualize metrics such as CPU usage, memory, and network I/O.

<code>- job_name: 's1'
  static_configs:
    - targets: ['172.17.211.143:9200']
</code>

Example Prometheus query for CPU usage:

<code>avg(irate(node_cpu_seconds_total{instance=~"$node",mode="system"}[30m])) by (instance)
+ avg(irate(node_cpu_seconds_total{instance=~"$node",mode="user"}[30m])) by (instance)
+ avg(irate(node_cpu_seconds_total{instance=~"$node",mode="iowait"}[30m])) by (instance)
+ 1 - avg(irate(node_cpu_seconds_total{instance=~"$node",mode="idle"}[30m])) by (instance)
</code>

The query combines system, user, and iowait CPU time and subtracts idle time to obtain overall CPU utilization.

Summary

The guide demonstrates how to replace manual JMeter HTML reports with an automated pipeline: JMeter → InfluxDB → Grafana for application‑level metrics, and node_exporter → Prometheus → Grafana for OS‑level metrics. Understanding the data source and meaning of each counter is essential for accurate performance analysis.

metricsPerformance MonitoringPrometheusJMeterInfluxDBGrafananode exporter
Efficient Ops
Written by

Efficient Ops

This public account is maintained by Xiaotianguo and friends, regularly publishing widely-read original technical articles. We focus on operations transformation and accompany you throughout your operations career, growing together happily.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.