Gatling Report

Gatling Report

Gatling Report screenshot 1
Gatling Report screenshot 2
Gatling Report screenshot 3
Gatling Report screenshot 4
Gatling Report screenshot 5
Gatling Report screenshot 6
Gatling Report screenshot 7
Gatling Report screenshot 8
Gatling Report screenshot 9
Gatling Report screenshot 10
Gatling Report screenshot 11
Gatling Report screenshot 12
Gatling Report screenshot 13
Gatling Report screenshot 14

Change log

The new version of Gatling doesn’t support graphite output anymore.

Please use another tool perfana/x2i or perfana/g2i instead of InfluxDB v1 graphite input or Telegraf graphite input plugin. There is a new dashboard for the x2i or g2i: https://grafana.com/grafana/dashboards/21776-gatling/ . There is an instruction about using InfluxDB v2 or VictoriaMetrics as metric storages: https://github.com/perfana/x2i/issues/2

Demo

Open model: Gatling Grafana Report openmodel-rampusers2

Closed model: Gatling Grafana Report closemodel-incrementconcurrentusers

Install

Use Grafana 6.5 - 6.7 for develop, modification and work.

Use Grafana 7.0.3 beta for work and small modification: Grafana 7.0 did not support creating links with ${cell} params in URL, but support vew and modify links with ${cell} in Table Panel Old (backward compatibility).

Example docker containter start with plugins and settings: /devenv/devenv.run.grafana.sh

#!/bin/sh -x

git clone https://github.com/polarnik/gatling-grafana-dashboard.git
cd gatling-grafana-dashboard/devenv

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
ID=$(id -u)

docker network create loadlab
docker pull grafana/grafana

docker run --name=grafana \
 --network=loadlab --user $ID -p 3000:3000 \
 -v "$DIR/grafana.ini":/etc/grafana/grafana.ini \
 -v "$DIR/plugins":/var/lib/grafana/plugins \
 -v "$DIR/provisioning":/etc/grafana/provisioning \
 -v "$DIR/var/lib/grafana":/var/lib/grafana \
 -v "$DIR/usr/share/grafana":/var/usr/share/grafana \
 -v "$DIR/var/log/grafana":/var/log/grafana \
 grafana/grafana
  1. Change datasource settings in /devenv/provisioning/datasources/influxdb-Gatling_TCP.yml - for example set basicAuth: false and database: gatling
  2. Open http://localhost:3000/d/gatlingTrendWithLink, demo link: http://84.201.161.113:3000/d/gatlingTrendLink
  3. Select Test Run in Navigate menu, go to link http://localhost:3000/d/gatling/…some…params…
  4. View http://localhost:3000/d/gatling report

Default admin password in grafana.ini:

Source code and developer environment

Features

  • Full Copy of HTML Gatling Report - all graphs and tables
  • Distributed testing support - sum metrics from multiple hostname (load agent) with filtering by hostname
  • Support grouping request
  • Filtering by RunID
  • Navigate Menu
  • Support Closing Load Model - new graph “Concurrent Users”

Helpers

  • Dynamic select Grafana Granularity: $g = gatling write period
  • Dynamic calculate test Duration for RunID tag
  • Highlight zero values in tables
  • Support both Dark and White Grafana themes

TODO

View

Full View

Filter by Load Station (default All - sum result from multiple load agent). Time Link - link to navigate to other Test Run with same Simulation name:

Filter by Group (support Gatling Group store, filtering and visualise) for Group 1, 2, 3 levels:

Test Report header:

  • Simulation name
  • Test RunID
  • Names of Load Stations
  • Test Duration

And Indicators

  • time <= 40 ms
  • time > 40 && time <= 100
  • time > 100

Treshold 40, 100 get from Grafana variables (may be changed via URL params &var-duration_1=40&var-duration_2=100):

Global Information / Statistics:

  • Group names: Group (level 1), Group (level 2), Group (level 3) if needed
  • Requests - request name
    • synthetic request Global Information - all request alias
  • Total - total count (default sort order by Total DESC)
  • OK - ok count
  • KO - not ok count
  • %KO = KO for current request / Total for Global Information

InfluxDB.conf

Full influxdb.conf example: /devenv/influxdb.conf

# Determines whether the graphite endpoint is enabled.
enabled = true
database = "gatling"
# retention-policy = ""
bind-address = ":2003"
protocol = "tcp"
# consistency-level = "one"
templates = [
  "gatling.*.users.*.*      measurement.simulation.measurement.request.field",
  "gatling.*.*.*.*.*.*   measurement.simulation.group1.group2.request.status.field   group=2",
  "gatling.*.*.*.*.*   measurement.simulation.group1.request.status.field   group=1",
  "gatling.*.*.*.*   measurement.simulation.request.status.field   group=0",

  "v2.gatling.*.*.*.users.*.*  .measurement.run.host.simulation.measurement.request.field",
  "v2.gatling.*.*.*.*.*.*.*.*  .measurement.run.host.simulation.group1.group2.request.status.field   group=2",
  "v2.gatling.*.*.*.*.*.*.*  .measurement.run.host.simulation.group1.request.status.field   group=1",
  "v2.gatling.*.*.*.*.*.*  .measurement.run.host.simulation.request.status.field   group=0",
]

# These next lines control how batching works. You should have this enabled
# otherwise you could get dropped metrics or poor performance. Batching
# will buffer points in memory if you have many coming in.

# Flush if this many points get buffered
batch-size = 5000

# number of batches that may be pending in memory
batch-pending = 10

# Flush at least this often even if we haven't hit buffer limit
batch-timeout = "10s"

### This string joins multiple matching 'measurement' values providing more control over the final measurement name.
separator = "."

### Default tags that will be added to all metrics.  These can be overridden at the template level
### or by tags extracted from metric
# tags = ["region=us-east", "zone=1c"]

Gatling (settings for support RunID and Hostname filter in Gatling Report)

Project Example: https://github.com/polarnik/gatling-report-example

What is RunID?

  • RunID is a unique identificator of Gatling test runs, with starts in same time.
  • Load agent hostname - not unique, Simulation - not unique (it is load profile name), but RunID + Simulation + Hostname - unique result.
  • RunID combine multiple load agents results (multiple hostname) into one Gatling test run: filter by RunID + Simulation, but not by Hostname (host = All).

Settings in Gatling.conf

Example /src/test/resources/gatling.conf

  1. Enable graphite support via gatling.data.writers (gatling.data.writers = [graphite])
  2. Disable or paramertize rootPathPrefix in gatling.data.graphite:
    • Comment rootPathPrefix in gatling.data.graphite section - for support override this prefix and pass RunId and Hostname from Gatling to InfluxDB
    • Use Environment Variable GATLING_PREFIX forrootPathPrefix value - for support override this prefix and pass RunId and Hostname from Gatling to InfluxDB

Short example:

gatling {
  data {
    writers = [console, file, graphite]
    console {
      light = false          # When set to true, displays a light version without detailed request stats
      writePeriod = 10       # Write interval, in seconds
    }
    file {
      light = false          # Full Information
      bufferSize = 8192      # FileDataWriter's internal data buffer size, in bytes
    }
    leak {
      noActivityTimeout = 60 # Period, in seconds, for which Gatling may have no activity before considering a leak may be happening
    }
    graphite {
      light = false          # Full Information
      host = "localhost"     # The host where the Carbon server is located
      port = 2003            # The port to which the Carbon server listens to
      protocol = "tcp"       # The protocol used to send data to Carbon (currently supported : "tcp", "udp")
      #rootPathPrefix = "gatling" #! Disable default prefix for using custom prefix: v2.gatling.{run}.{host} 
      bufferSize = 81920     # Internal data buffer size, in bytes
      writePeriod = 1        # Write period, in seconds
    }
  }
}

or

gatling {
  data {
    writers = [console, file, graphite]
    console {
      light = false          # When set to true, displays a light version without detailed request stats
      writePeriod = 10       # Write interval, in seconds
    }
    file {
      light = false          # Full Information
      bufferSize = 8192      # FileDataWriter's internal data buffer size, in bytes
    }
    leak {
      noActivityTimeout = 60 # Period, in seconds, for which Gatling may have no activity before considering a leak may be happening
    }
    graphite {
      light = false          # Full Information
      host = "localhost"     # The host where the Carbon server is located
      port = 2003            # The port to which the Carbon server listens to
      protocol = "tcp"       # The protocol used to send data to Carbon (currently supported : "tcp", "udp")
      rootPathPrefix=${?GATLING_PREFIX} #! Override default prefix via envirinment variable with: v2.gatling.{run}.{host} 
      bufferSize = 81920     # Internal data buffer size, in bytes
      writePeriod = 1        # Write period, in seconds
    }
  }
}

Start Gatling test with custom rootPathPrefix

Calculate RunID via bash script: gatling-report-example/start.gatling.rootPathPrefix.sh with round date time for 5 minutes

#!/bin/bash
# ./start.gatling.rootPathPrefix.sh

datetimePrefix=`date '+%Y-%m-%d_%H'`
dateTimeMinute=`date '+%M'`

round=5
roundMinute=$(expr "$dateTimeMinute" / $round)
roundMinute=$(expr "$roundMinute" \* $round)
roundMinute=$(printf "%02d" $roundMinute)

export GATLING_PREFIX="v2.gatling.$datetimePrefix:$roundMinute.`hostname`"

echo $GATLING_PREFIX

Calculate RunID via Scala script: gatling-report-example/src/test/scala/io/qaload/gatling/reportExample/setting/TestConfig.scala with round date time for 5 minutes

class RunIdConvertor extends Converter[String] {

  def getRoundStartTime(roundMinute: Int): String = {
    val dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd_HH")
    val startTime = OffsetDateTime.now().format(dateTimeFormatter)
    val date = new Date()                  // given date
    val calendar = new GregorianCalendar() // creates a new calendar instance
    calendar.setTime(date)                 // assigns calendar to given date
    val minute = calendar.get(Calendar.MINUTE)
    val minuteRound = round(floor( 1.0d * minute / roundMinute) * roundMinute)
    s"${startTime}:${"%02d".format(minuteRound)}"
  }

  def convert(targetMethod: Method, text: String): String = {
    if (text != "") {
      text
    } else {
      getRoundStartTime(5)
    }
  }
}

Case 1: SBT and pass RunID + Hostname via Command Line

Example: gatling-report-example/start.test.maven.sh

If comment rootPathPrefix in gatling.data.graphite

#!/bin/bash

GATLING_ROOT_PATH_PREFIX=`./start.gatling.rootPathPrefix.sh`

sbt -Dgatling.data.graphite.rootPathPrefix=$GATLING_ROOT_PATH_PREFIX  "gatling:testOnly io.qaload.gatling.reportExample.simulation.OpenModel_AtOnceUsers"

If use Environment Variable GATLING_PREFIX forrootPathPrefix

#!/bin/bash

GATLING_ROOT_PATH_PREFIX=`./start.gatling.rootPathPrefix.sh`

GATLING_ROOT_PATH_PREFIX=$GATLING_ROOT_PATH_PREFIX sbt "gatling:testOnly io.qaload.gatling.reportExample.simulation.OpenModel_AtOnceUsers"

Case 2: Maven and pass RunID + Hostname via Command Line

Example: gatling-report-example/start.test.maven.sh

If use Environment Variable GATLING_PREFIX forrootPathPrefix

#!/bin/bash

GATLING_ROOT_PATH_PREFIX=`./start.gatling.rootPathPrefix.sh`

GATLING_ROOT_PATH_PREFIX=$GATLING_ROOT_PATH_PREFIX mvn gatling:test -Dsimulation=OpenModel_AtOnceUsers

Case 3: IntelliJ IDEA and pass RunID + Hostname via App parameters

Example: gatling-report-example/src/test/scala/Engine.scala

Revisions
RevisionDescriptionCreated

Get this dashboard

Import the dashboard template

or

Download JSON

Datasource
Dependencies