diff --git a/testing-modules/gatling-java/Dockerfile b/testing-modules/gatling-java/Dockerfile new file mode 100644 index 000000000000..370d07c12c39 --- /dev/null +++ b/testing-modules/gatling-java/Dockerfile @@ -0,0 +1,6 @@ +FROM openjdk:17-jdk-slim + +COPY target/gatling-java.jar app.jar +ENTRYPOINT ["java","-jar","/app.jar"] + +EXPOSE 8080 diff --git a/testing-modules/gatling-java/README.md b/testing-modules/gatling-java/README.md index 02c271cd0752..ee3ab35f213a 100644 --- a/testing-modules/gatling-java/README.md +++ b/testing-modules/gatling-java/README.md @@ -1,7 +1,10 @@ ### Relevant Articles: + - [Load Testing Rest Endpoint Using Gatling](https://www.baeldung.com/gatling-load-testing-rest-endpoint) - [How to Display a Full HTTP Response Body With Gatling](https://www.baeldung.com/java-gatling-show-response-body) - ### Running a simualtion - To run the simulation from command prompt use mvn gatling:test + +To run the simulations from command prompt use `mvn gatling:test`. This will trigger all 3 simulations: EmployeeRegistrationSimulation, FetchSinglePostSimulation and FetchSinglePostSimulationLog. + +For executing any other simulations, use `mvn gatling:test -Dgatling.simulationClass=org.baeldung.FastEndpointSimulation` diff --git a/testing-modules/gatling-java/docker-compose.yml b/testing-modules/gatling-java/docker-compose.yml new file mode 100644 index 000000000000..d5d89d3a5d2c --- /dev/null +++ b/testing-modules/gatling-java/docker-compose.yml @@ -0,0 +1,47 @@ +version: '3' + +services: + influxdb: + build: influxDb + container_name: influxdb + ports: + - '8086:8086' + - '2003:2003' + environment: + - INFLUX_USER=admin + - INFLUX_PASSWORD=admin + - INFLUX_DB=influx + volumes: + - influxdb_data:/var/lib/influxdb + + prometheus: + build: prometheus + container_name: prometheus + depends_on: + - service + ports: + - "9090:9090" + volumes: + - prometheus_data:/prometheus + + grafana: + build: grafana + container_name: grafana + ports: + - "3000:3000" + environment: + - GF_SECURITY_ADMIN_USER=admin + - GF_SECURITY_ADMIN_PASSWORD=admin + volumes: + - grafana_data:/var/lib/grafana + + service: + build: . + container_name: service + ports: + - "8080:8080" + +volumes: + influxdb_data: {} + grafana_data: {} + prometheus_data: {} diff --git a/testing-modules/gatling-java/grafana/Dockerfile b/testing-modules/gatling-java/grafana/Dockerfile new file mode 100644 index 000000000000..aa440202e985 --- /dev/null +++ b/testing-modules/gatling-java/grafana/Dockerfile @@ -0,0 +1,6 @@ +FROM grafana/grafana:10.2.2 + +COPY provisioning/ /etc/grafana/provisioning/ +COPY dashboards/ /etc/grafana/provisioning/dashboards + +EXPOSE 3000:3000 diff --git a/testing-modules/gatling-java/grafana/dashboards/application-metrics.json b/testing-modules/gatling-java/grafana/dashboards/application-metrics.json new file mode 100644 index 000000000000..77866cccecc7 --- /dev/null +++ b/testing-modules/gatling-java/grafana/dashboards/application-metrics.json @@ -0,0 +1,607 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "description": "", + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": 1, + "links": [], + "liveNow": false, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus", + "uid": "P525C2881E9E76938" + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 0 + }, + "hiddenSeries": false, + "id": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "10.2.2", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "/.*rate/", + "yaxis": 2 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "P525C2881E9E76938" + }, + "editorMode": "code", + "expr": "sum(http_server_requests_seconds_count) by (uri, status)", + "interval": "", + "legendFormat": "{{ uri }} - {{ status }}", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "P525C2881E9E76938" + }, + "expr": "sum(rate(application_responses_total[2m])) by (endpointName)", + "hide": false, + "interval": "", + "legendFormat": "{{ endpointName }} rate", + "refId": "B" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Total Responses", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": "Total", + "logBase": 1, + "show": true + }, + { + "format": "short", + "label": "TPS", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus", + "uid": "P525C2881E9E76938" + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 0 + }, + "hiddenSeries": false, + "id": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "10.2.2", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "/.*rate/", + "yaxis": 2 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "P525C2881E9E76938" + }, + "editorMode": "code", + "expr": "sum(rate(http_server_requests_seconds_count{status=~\"2..\"}[20s])) by (uri, status)", + "interval": "", + "legendFormat": "{{ uri }} - {{ status }}", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "P525C2881E9E76938" + }, + "editorMode": "code", + "expr": "sum(rate(http_server_requests_seconds_count{status=~\"4..\"}[20s])) by (uri, status)", + "hide": false, + "instant": false, + "legendFormat": "{{ uri }} - {{ status }}", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "P525C2881E9E76938" + }, + "editorMode": "code", + "expr": "sum(rate(http_server_requests_seconds_count{status=~\"5..\"}[20s])) by (uri, status)", + "hide": false, + "instant": false, + "legendFormat": "{{ uri }} - {{ status }}", + "range": true, + "refId": "C" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Transactions per Second (TPS)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:438", + "format": "ops", + "label": "Total", + "logBase": 1, + "show": true + }, + { + "$$hashKey": "object:439", + "format": "short", + "label": "TPS", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus", + "uid": "P525C2881E9E76938" + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 9 + }, + "hiddenSeries": false, + "id": 4, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "10.2.2", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "P525C2881E9E76938" + }, + "editorMode": "code", + "expr": "jvm_threads_states_threads", + "hide": false, + "interval": "", + "legendFormat": "Total '{{state}}' threads", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "P525C2881E9E76938" + }, + "editorMode": "code", + "expr": "jvm_threads_live_threads", + "hide": false, + "instant": false, + "legendFormat": "Total Threads", + "range": true, + "refId": "C" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "JVM Threads Totals", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus", + "uid": "P525C2881E9E76938" + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 9 + }, + "hiddenSeries": false, + "id": 7, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "10.2.2", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "/.*rate/", + "yaxis": 2 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "P525C2881E9E76938" + }, + "disableTextWrap": false, + "editorMode": "code", + "exemplar": false, + "expr": "sum by(uri, status) (rate(http_server_requests_seconds_sum[20s]) / rate(http_server_requests_seconds_count[20s]))", + "format": "time_series", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": true, + "instant": false, + "interval": "", + "legendFormat": "{{uri}} - {{status}}", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Response delays", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:409", + "format": "s", + "label": "Total", + "logBase": 1, + "show": true + }, + { + "$$hashKey": "object:410", + "format": "short", + "label": "TPS", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus", + "uid": "P525C2881E9E76938" + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 18 + }, + "hiddenSeries": false, + "id": 6, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "10.2.2", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "P525C2881E9E76938" + }, + "editorMode": "code", + "expr": "rate(jvm_threads_states_threads[1m])", + "hide": false, + "interval": "", + "legendFormat": "Rate of '{{state}}' threads", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "P525C2881E9E76938" + }, + "editorMode": "code", + "expr": "rate(jvm_threads_live_threads[1m])", + "hide": false, + "instant": false, + "legendFormat": "Rate of live threads", + "range": true, + "refId": "C" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "JVM Threads Rates", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + } + ], + "refresh": "5s", + "schemaVersion": 38, + "tags": [], + "templating": { + "list": [ + { + "current": { + "selected": false, + "text": "Prometheus-docker", + "value": "P525C2881E9E76938" + }, + "hide": 0, + "includeAll": false, + "multi": false, + "name": "Datasource", + "options": [], + "query": "prometheus", + "queryValue": "", + "refresh": 1, + "regex": "Prometheus-.*", + "skipUrlSync": false, + "type": "datasource" + } + ] + }, + "time": { + "from": "now-30m", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ] + }, + "timezone": "", + "title": "Application Metrics", + "uid": "e0tGbtKGz", + "version": 4, + "weekStart": "" +} diff --git a/testing-modules/gatling-java/grafana/dashboards/gatling-metrics.json b/testing-modules/gatling-java/grafana/dashboards/gatling-metrics.json new file mode 100644 index 000000000000..ff7f7d97cae4 --- /dev/null +++ b/testing-modules/gatling-java/grafana/dashboards/gatling-metrics.json @@ -0,0 +1,1281 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "influxdb", + "uid": "P951FEA4DE68E13C5" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": 2, + "links": [], + "liveNow": false, + "panels": [ + { + "datasource": { + "type": "influxdb", + "uid": "P951FEA4DE68E13C5" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 1, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "influxdb", + "uid": "P951FEA4DE68E13C5" + }, + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "measurement": "gatling.fastendpointsimulation.allRequests.all.count", + "orderByTime": "ASC", + "policy": "default", + "query": "SELECT mean(\"value\") FROM \"gatling.fastendpointsimulation.allRequests.all.count\" WHERE $timeFilter GROUP BY time($__interval) fill(null)", + "rawQuery": false, + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [] + } + ], + "title": "FAST - Requests sent Count", + "type": "timeseries" + }, + { + "datasource": { + "type": "influxdb", + "uid": "P951FEA4DE68E13C5" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 0 + }, + "id": 8, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "influxdb", + "uid": "P951FEA4DE68E13C5" + }, + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "measurement": "gatling.slowendpointsimulation.allRequests.all.count", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [] + } + ], + "title": "SLOW - Requests sent Count", + "type": "timeseries" + }, + { + "datasource": { + "type": "influxdb", + "uid": "P951FEA4DE68E13C5" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 8 + }, + "id": 7, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "influxdb", + "uid": "P951FEA4DE68E13C5" + }, + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "measurement": "gatling.fastendpointsimulation.allRequests.ok.count", + "orderByTime": "ASC", + "policy": "default", + "query": "SELECT mean(\"value\") FROM \"gatling.fastendpointsimulation.allRequests.ok.count\" WHERE $timeFilter GROUP BY time($__interval) fill(null)", + "rawQuery": false, + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [] + } + ], + "title": "FAST - Requests with 2xx response Count", + "type": "timeseries" + }, + { + "datasource": { + "type": "influxdb", + "uid": "P951FEA4DE68E13C5" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 8 + }, + "id": 9, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "influxdb", + "uid": "P951FEA4DE68E13C5" + }, + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "measurement": "gatling.slowendpointsimulation.allRequests.ok.count", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [] + } + ], + "title": "SLOW - Requests with 2xx response Count", + "type": "timeseries" + }, + { + "datasource": { + "type": "influxdb", + "uid": "P951FEA4DE68E13C5" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 16 + }, + "id": 3, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "influxdb", + "uid": "P951FEA4DE68E13C5" + }, + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "measurement": "gatling.fastendpointsimulation.allRequests.ko.count", + "orderByTime": "ASC", + "policy": "default", + "query": "SELECT mean(\"value\") FROM \"gatling.fastendpointsimulation.allRequests.ko.count\" WHERE $timeFilter GROUP BY time($__interval) fill(null)", + "rawQuery": false, + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [] + } + ], + "title": "FAST - Requests with error response Count", + "type": "timeseries" + }, + { + "datasource": { + "type": "influxdb", + "uid": "P951FEA4DE68E13C5" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 16 + }, + "id": 10, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "influxdb", + "uid": "P951FEA4DE68E13C5" + }, + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "measurement": "gatling.slowendpointsimulation.allRequests.ko.count", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [] + } + ], + "title": "SLOW - Requests with error response Count", + "type": "timeseries" + }, + { + "datasource": { + "type": "influxdb", + "uid": "P951FEA4DE68E13C5" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 24 + }, + "id": 4, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "influxdb", + "uid": "P951FEA4DE68E13C5" + }, + "groupBy": [ + { + "params": [ + "10s" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "measurement": "gatling.fastendpointsimulation.allRequests.all.percentiles95", + "orderByTime": "ASC", + "policy": "default", + "query": "SELECT mean(\"value\") FROM \"gatling.fastendpointsimulation.allRequests.all.percentiles95\" WHERE $timeFilter GROUP BY time($__interval) fill(null)", + "rawQuery": false, + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [] + } + ], + "title": "FAST - Requests 95 Percentile", + "type": "timeseries" + }, + { + "datasource": { + "type": "influxdb", + "uid": "P951FEA4DE68E13C5" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 24 + }, + "id": 11, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "influxdb", + "uid": "P951FEA4DE68E13C5" + }, + "groupBy": [ + { + "params": [ + "10s" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "measurement": "gatling.slowendpointsimulation.allRequests.all.percentiles95", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [] + } + ], + "title": "SLOW - Requests 95 Percentile", + "type": "timeseries" + }, + { + "datasource": { + "type": "influxdb", + "uid": "P951FEA4DE68E13C5" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 32 + }, + "id": 6, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "influxdb", + "uid": "P951FEA4DE68E13C5" + }, + "groupBy": [ + { + "params": [ + "10s" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "measurement": "gatling.fastendpointsimulation.allRequests.all.percentiles75", + "orderByTime": "ASC", + "policy": "default", + "query": "SELECT mean(\"value\") FROM \"gatling.fastendpointsimulation.allRequests.all.percentiles75\" WHERE $timeFilter GROUP BY time(10s) fill(null)", + "rawQuery": false, + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [] + } + ], + "title": "FAST - Requests 75 Percentile", + "type": "timeseries" + }, + { + "datasource": { + "type": "influxdb", + "uid": "P951FEA4DE68E13C5" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 32 + }, + "id": 12, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "influxdb", + "uid": "P951FEA4DE68E13C5" + }, + "groupBy": [ + { + "params": [ + "10s" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "measurement": "gatling.slowendpointsimulation.allRequests.all.percentiles75", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [] + } + ], + "title": "SLOW - Requests 75 Percentile", + "type": "timeseries" + } + ], + "refresh": "30s", + "schemaVersion": 38, + "tags": [], + "templating": { + "list": [] + }, + "time": { + "from": "now-30m", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "Gatling Metrics", + "version": 9, + "weekStart": "" +} diff --git a/testing-modules/gatling-java/grafana/provisioning/dashboards/dashboard.yml b/testing-modules/gatling-java/grafana/provisioning/dashboards/dashboard.yml new file mode 100644 index 000000000000..1685fec552c8 --- /dev/null +++ b/testing-modules/gatling-java/grafana/provisioning/dashboards/dashboard.yml @@ -0,0 +1,12 @@ +apiVersion: 1 + +providers: + - name: 'dashboards' + folder: '' + type: file + disableDeletion: false + allowUiUpdates: true + editable: true + options: + path: /etc/grafana/provisioning/dashboards + foldersFromFilesStructure: true diff --git a/testing-modules/gatling-java/grafana/provisioning/datasources/datasource.yml b/testing-modules/gatling-java/grafana/provisioning/datasources/datasource.yml new file mode 100644 index 000000000000..83bf24a244b8 --- /dev/null +++ b/testing-modules/gatling-java/grafana/provisioning/datasources/datasource.yml @@ -0,0 +1,34 @@ +# config file version +apiVersion: 1 + +# list of datasources that should be deleted from the database +#deleteDatasources: +# - name: Prometheus +# orgId: 1 + +# list of datasources to insert/update depending +# whats available in the database +datasources: + - name: Prometheus-docker + type: prometheus + isDefault: false + access: proxy + url: http://prometheus:9090 + basicAuth: false + jsonData: + graphiteVersion: "1.1" + tlsAuth: false + tlsAuthWithCACert: false + version: 1 + editable: true + - name: InfluxDB + type: influxdb + uid: P951FEA4DE68E13C5 + isDefault: false + access: proxy + url: http://influxdb:8086 + basicAuth: false + jsonData: + dbName: "graphite" + version: 1 + editable: true diff --git a/testing-modules/gatling-java/influxDb/Dockerfile b/testing-modules/gatling-java/influxDb/Dockerfile new file mode 100644 index 000000000000..d6d03f435c1c --- /dev/null +++ b/testing-modules/gatling-java/influxDb/Dockerfile @@ -0,0 +1,8 @@ +FROM influxdb:1.3.1-alpine + +WORKDIR /app +COPY entrypoint.sh ./ +RUN chmod u+x entrypoint.sh +COPY influxdb.conf /etc/influxdb/influxdb.conf + +ENTRYPOINT ["/app/entrypoint.sh"] diff --git a/testing-modules/gatling-java/influxDb/entrypoint.sh b/testing-modules/gatling-java/influxDb/entrypoint.sh new file mode 100644 index 000000000000..bb9cdb1153de --- /dev/null +++ b/testing-modules/gatling-java/influxDb/entrypoint.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env sh + +echo "running script influxdb" + +if [ ! -f "/var/lib/influxdb/.init" ]; then + echo "influx init missing" + exec influxd -config /etc/influxdb/influxdb.conf $@ & + + until wget -q "http://localhost:8086/ping" 2> /dev/null; do + sleep 1 + done + + influx -host=localhost -port=8086 -execute="CREATE USER ${INFLUX_USER} WITH PASSWORD '${INFLUX_PASSWORD}' WITH ALL PRIVILEGES" + influx -host=localhost -port=8086 -execute="CREATE DATABASE ${INFLUX_DB}" + + touch "/var/lib/influxdb/.init" + + kill -s TERM %1 +fi + +exec influxd $@ diff --git a/testing-modules/gatling-java/influxDb/influxdb.conf b/testing-modules/gatling-java/influxDb/influxdb.conf new file mode 100644 index 000000000000..40835a937593 --- /dev/null +++ b/testing-modules/gatling-java/influxDb/influxdb.conf @@ -0,0 +1,622 @@ +### Welcome to the InfluxDB configuration file. + +# The values in this file override the default values used by the system if +# a config option is not specified. The commented out lines are the configuration +# field and the default value used. Uncommenting a line and changing the value +# will change the value used at runtime when the process is restarted. + +# Once every 24 hours InfluxDB will report usage data to usage.influxdata.com +# The data includes a random ID, os, arch, version, the number of series and other +# usage data. No data from user databases is ever transmitted. +# Change this option to true to disable reporting. +# reporting-disabled = false + +# Bind address to use for the RPC service for backup and restore. +# bind-address = "127.0.0.1:8088" + +### +### [meta] +### +### Controls the parameters for the Raft consensus group that stores metadata +### about the InfluxDB cluster. +### + +[meta] + # Where the metadata/raft database is stored + dir = "/var/lib/influxdb/meta" + + # Automatically create a default retention policy when creating a database. + # retention-autocreate = true + + # If log messages are printed for the meta service + # logging-enabled = true + +### +### [data] +### +### Controls where the actual shard data for InfluxDB lives and how it is +### flushed from the WAL. "dir" may need to be changed to a suitable place +### for your system, but the WAL settings are an advanced configuration. The +### defaults should work for most systems. +### + +[data] + # The directory where the TSM storage engine stores TSM files. + dir = "/var/lib/influxdb/data" + + # The directory where the TSM storage engine stores WAL files. + wal-dir = "/var/lib/influxdb/wal" + + # The amount of time that a write will wait before fsyncing. A duration + # greater than 0 can be used to batch up multiple fsync calls. This is useful for slower + # disks or when WAL write contention is seen. A value of 0s fsyncs every write to the WAL. + # Values in the range of 0-100ms are recommended for non-SSD disks. + # wal-fsync-delay = "0s" + + + # The type of shard index to use for new shards. The default is an in-memory index that is + # recreated at startup. A value of "tsi1" will use a disk based index that supports higher + # cardinality datasets. + # index-version = "inmem" + + # Trace logging provides more verbose output around the tsm engine. Turning + # this on can provide more useful output for debugging tsm engine issues. + # trace-logging-enabled = false + + # Whether queries should be logged before execution. Very useful for troubleshooting, but will + # log any sensitive data contained within a query. + # query-log-enabled = true + + # It is possible to collect statistics of points written per-measurement and/or per-login. + # These can be accessed via the monitoring subsystem. + # ingress-metric-by-measurement-enabled = false + # ingress-metric-by-login-enabled = false + + + # Provides more error checking. For example, SELECT INTO will err out inserting an +/-Inf value + # rather than silently failing. + # strict-error-handling = false + + # Validates incoming writes to ensure keys only have valid unicode characters. + # This setting will incur a small overhead because every key must be checked. + # validate-keys = false + + # Settings for the TSM engine + + # CacheMaxMemorySize is the maximum size a shard's cache can + # reach before it starts rejecting writes. + # Valid size suffixes are k, m, or g (case insensitive, 1024 = 1k). + # Values without a size suffix are in bytes. + # cache-max-memory-size = "1g" + + # CacheSnapshotMemorySize is the size at which the engine will + # snapshot the cache and write it to a TSM file, freeing up memory + # Valid size suffixes are k, m, or g (case insensitive, 1024 = 1k). + # Values without a size suffix are in bytes. + # cache-snapshot-memory-size = "25m" + + # CacheSnapshotWriteColdDuration is the length of time at + # which the engine will snapshot the cache and write it to + # a new TSM file if the shard hasn't received writes or deletes + # cache-snapshot-write-cold-duration = "10m" + + # CompactFullWriteColdDuration is the duration at which the engine + # will compact all TSM files in a shard if it hasn't received a + # write or delete + # compact-full-write-cold-duration = "4h" + + # The maximum number of concurrent full and level compactions that can run at one time. A + # value of 0 results in 50% of runtime.GOMAXPROCS(0) used at runtime. Any number greater + # than 0 limits compactions to that value. This setting does not apply + # to cache snapshotting. + # max-concurrent-compactions = 0 + + # MaxConcurrentDeletes is the maximum number of simultaneous DELETE calls on a shard + # The default is 1, and should be left unchanged for most users + # MaxConcurrentDeletes = 1 + + # CompactThroughput is the rate limit in bytes per second that we + # will allow TSM compactions to write to disk. Note that short bursts are allowed + # to happen at a possibly larger value, set by CompactThroughputBurst + # compact-throughput = "48m" + + # CompactThroughputBurst is the rate limit in bytes per second that we + # will allow TSM compactions to write to disk. + # compact-throughput-burst = "48m" + + # If true, then the mmap advise value MADV_WILLNEED will be provided to the kernel with respect to + # TSM files. This setting has been found to be problematic on some kernels, and defaults to off. + # It might help users who have slow disks in some cases. + # tsm-use-madv-willneed = false + + # Settings for the inmem index + + # The maximum series allowed per database before writes are dropped. This limit can prevent + # high cardinality issues at the database level. This limit can be disabled by setting it to + # 0. + # max-series-per-database = 1000000 + + # The maximum number of tag values per tag that are allowed before writes are dropped. This limit + # can prevent high cardinality tag values from being written to a measurement. This limit can be + # disabled by setting it to 0. + # max-values-per-tag = 100000 + + # Settings for the tsi1 index + + # The threshold, in bytes, when an index write-ahead log file will compact + # into an index file. Lower sizes will cause log files to be compacted more + # quickly and result in lower heap usage at the expense of write throughput. + # Higher sizes will be compacted less frequently, store more series in-memory, + # and provide higher write throughput. + # Valid size suffixes are k, m, or g (case insensitive, 1024 = 1k). + # Values without a size suffix are in bytes. + # max-index-log-file-size = "1m" + + # The size of the internal cache used in the TSI index to store previously + # calculated series results. Cached results will be returned quickly from the cache rather + # than needing to be recalculated when a subsequent query with a matching tag key/value + # predicate is executed. Setting this value to 0 will disable the cache, which may + # lead to query performance issues. + # This value should only be increased if it is known that the set of regularly used + # tag key/value predicates across all measurements for a database is larger than 100. An + # increase in cache size may lead to an increase in heap usage. + series-id-set-cache-size = 100 + +### +### [coordinator] +### +### Controls the clustering service configuration. +### + +[coordinator] + # The default time a write request will wait until a "timeout" error is returned to the caller. + # write-timeout = "10s" + + # The maximum number of concurrent queries allowed to be executing at one time. If a query is + # executed and exceeds this limit, an error is returned to the caller. This limit can be disabled + # by setting it to 0. + # max-concurrent-queries = 0 + + # The maximum time a query will is allowed to execute before being killed by the system. This limit + # can help prevent run away queries. Setting the value to 0 disables the limit. + # query-timeout = "0s" + + # The time threshold when a query will be logged as a slow query. This limit can be set to help + # discover slow or resource intensive queries. Setting the value to 0 disables the slow query logging. + # log-queries-after = "0s" + + # Enables the logging of queries that are killed as a result of exceeding `query-timeout` + # log-timedout-queries = false + + # The maximum number of points a SELECT can process. A value of 0 will make + # the maximum point count unlimited. This will only be checked every second so queries will not + # be aborted immediately when hitting the limit. + # max-select-point = 0 + + # The maximum number of series a SELECT can run. A value of 0 will make the maximum series + # count unlimited. + # max-select-series = 0 + + # The maximum number of group by time bucket a SELECT can create. A value of zero will max the maximum + # number of buckets unlimited. + # max-select-buckets = 0 + + # Whether to print a list of running queries when a data node receives a SIGTERM (sent when a process + # exceeds a container memory limit, or by the kill command. + # termination-query-log = false + +### +### [retention] +### +### Controls the enforcement of retention policies for evicting old data. +### + +[retention] + # Determines whether retention policy enforcement enabled. + # enabled = true + + # The interval of time when retention policy enforcement checks run. + # check-interval = "30m" + +### +### [shard-precreation] +### +### Controls the precreation of shards, so they are available before data arrives. +### Only shards that, after creation, will have both a start- and end-time in the +### future, will ever be created. Shards are never precreated that would be wholly +### or partially in the past. + +[shard-precreation] + # Determines whether shard pre-creation service is enabled. + # enabled = true + + # The interval of time when the check to pre-create new shards runs. + # check-interval = "10m" + + # The default period ahead of the endtime of a shard group that its successor + # group is created. + # advance-period = "30m" + +### +### Controls the system self-monitoring, statistics and diagnostics. +### +### The internal database for monitoring data is created automatically if +### if it does not already exist. The target retention within this database +### is called 'monitor' and is also created with a retention period of 7 days +### and a replication factor of 1, if it does not exist. In all cases the +### this retention policy is configured as the default for the database. + +[monitor] + # Whether to record statistics internally. + # store-enabled = true + + # The destination database for recorded statistics + # store-database = "_internal" + + # The interval at which to record statistics + # store-interval = "10s" + +### +### [http] +### +### Controls how the HTTP endpoints are configured. These are the primary +### mechanism for getting data into and out of InfluxDB. +### + +[http] + # Determines whether HTTP endpoint is enabled. + # enabled = true + + # Determines whether the Flux query endpoint is enabled. + # flux-enabled = false + + # Determines whether the Flux query logging is enabled. + # flux-log-enabled = false + + # The bind address used by the HTTP service. + # bind-address = ":8086" + + # Determines whether user authentication is enabled over HTTP/HTTPS. + # auth-enabled = false + + # The default realm sent back when issuing a basic auth challenge. + # realm = "InfluxDB" + + # Determines whether HTTP request logging is enabled. + # log-enabled = true + + # Determines whether the HTTP write request logs should be suppressed when the log is enabled. + # suppress-write-log = false + + # When HTTP request logging is enabled, this option specifies the path where + # log entries should be written. If unspecified, the default is to write to stderr, which + # intermingles HTTP logs with internal InfluxDB logging. + # + # If influxd is unable to access the specified path, it will log an error and fall back to writing + # the request log to stderr. + # access-log-path = "" + + # Filters which requests should be logged. Each filter is of the pattern NNN, NNX, or NXX where N is + # a number and X is a wildcard for any number. To filter all 5xx responses, use the string 5xx. + # If multiple filters are used, then only one has to match. The default is to have no filters which + # will cause every request to be printed. + # access-log-status-filters = [] + + # Determines whether detailed write logging is enabled. + # write-tracing = false + + # Determines whether the pprof endpoint is enabled. This endpoint is used for + # troubleshooting and monitoring. + # pprof-enabled = true + + # Enables authentication on pprof endpoints. Users will need admin permissions + # to access the pprof endpoints when this setting is enabled. This setting has + # no effect if either auth-enabled or pprof-enabled are set to false. + # pprof-auth-enabled = false + + # Enables a pprof endpoint that binds to localhost:6060 immediately on startup. + # This is only needed to debug startup issues. + # debug-pprof-enabled = false + + # Enables authentication on the /ping, /metrics, and deprecated /status + # endpoints. This setting has no effect if auth-enabled is set to false. + # ping-auth-enabled = false + + # Enables authentication on prometheus remote read api. This setting has no + # effect if auth-enabled is set to false. + # prom-read-auth-enabled = false + + # Determines whether HTTPS is enabled. + # https-enabled = false + + # The SSL certificate to use when HTTPS is enabled. + # https-certificate = "/etc/ssl/influxdb.pem" + + # Use a separate private key location. + # https-private-key = "" + + # The JWT auth shared secret to validate requests using JSON web tokens. + # shared-secret = "" + + # The default chunk size for result sets that should be chunked. + # max-row-limit = 0 + + # The maximum number of HTTP connections that may be open at once. New connections that + # would exceed this limit are dropped. Setting this value to 0 disables the limit. + # max-connection-limit = 0 + + # Enable http service over unix domain socket + # unix-socket-enabled = false + + # The path of the unix domain socket. + # bind-socket = "/var/run/influxdb.sock" + + # The maximum size of a client request body, in bytes. Setting this value to 0 disables the limit. + # max-body-size = 25000000 + + # The maximum number of writes processed concurrently. + # Setting this to 0 disables the limit. + # max-concurrent-write-limit = 0 + + # The maximum number of writes queued for processing. + # Setting this to 0 disables the limit. + # max-enqueued-write-limit = 0 + + # The maximum duration for a write to wait in the queue to be processed. + # Setting this to 0 or setting max-concurrent-write-limit to 0 disables the limit. + # enqueued-write-timeout = 0 + + # User supplied HTTP response headers + # + # [http.headers] + # X-Header-1 = "Header Value 1" + # X-Header-2 = "Header Value 2" + +### +### [logging] +### +### Controls how the logger emits logs to the output. +### + +[logging] + # Determines which log encoder to use for logs. Available options + # are auto, logfmt, and json. auto will use a more user-friendly + # output format if the output terminal is a TTY, but the format is not as + # easily machine-readable. When the output is a non-TTY, auto will use + # logfmt. + # format = "auto" + + # Determines which level of logs will be emitted. The available levels + # are error, warn, info, and debug. Logs that are equal to or above the + # specified level will be emitted. + # level = "info" + + # Suppresses the logo output that is printed when the program is started. + # The logo is always suppressed if STDOUT is not a TTY. + # suppress-logo = false + +### +### [subscriber] +### +### Controls the subscriptions, which can be used to fork a copy of all data +### received by the InfluxDB host. +### + +[subscriber] + # Determines whether the subscriber service is enabled. + # enabled = true + + # The default timeout for HTTP writes to subscribers. + # http-timeout = "30s" + + # Allows insecure HTTPS connections to subscribers. This is useful when testing with self- + # signed certificates. + # insecure-skip-verify = false + + # The path to the PEM encoded CA certs file. If the empty string, the default system certs will be used + # ca-certs = "" + + # The number of writer goroutines processing the write channel. + # write-concurrency = 40 + + # The number of in-flight writes buffered in the write channel. + # write-buffer-size = 1000 + + +### +### [[graphite]] +### +### Controls one or many listeners for Graphite data. +### + +[[graphite]] + # Determines whether the graphite endpoint is enabled. + enabled = true + database = "graphite" + retention-policy = "" + bind-address = ":2003" + protocol = "tcp" + consistency-level = "one" + + batch-size = 5000 + batch-pending = 10 + batch-timeout = "1s" + separator = "." + udp-read-buffer = 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 = "1s" + + # UDP Read buffer size, 0 means OS default. UDP listener will fail if set above OS max. + # udp-read-buffer = 0 + + ### 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"] + + ### Each template line requires a template pattern. It can have an optional + ### filter before the template and separated by spaces. It can also have optional extra + ### tags following the template. Multiple tags should be separated by commas and no spaces + ### similar to the line protocol format. There can be only one default template. + # templates = [ + # "*.app env.service.resource.measurement", + # # Default template + # "server.*", + # ] + +### +### [collectd] +### +### Controls one or many listeners for collectd data. +### + +[[collectd]] + # enabled = false + # bind-address = ":25826" + # database = "collectd" + # retention-policy = "" + # + # The collectd service supports either scanning a directory for multiple types + # db files, or specifying a single db file. + # typesdb = "/usr/local/share/collectd" + # + # security-level = "none" + # auth-file = "/etc/collectd/auth_file" + + # 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" + + # UDP Read buffer size, 0 means OS default. UDP listener will fail if set above OS max. + # read-buffer = 0 + + # Multi-value plugins can be handled two ways. + # "split" will parse and store the multi-value plugin data into separate measurements + # "join" will parse and store the multi-value plugin as a single multi-value measurement. + # "split" is the default behavior for backward compatibility with previous versions of influxdb. + # parse-multivalue-plugin = "split" +### +### [opentsdb] +### +### Controls one or many listeners for OpenTSDB data. +### + +[[opentsdb]] + # enabled = false + # bind-address = ":4242" + # database = "opentsdb" + # retention-policy = "" + # consistency-level = "one" + # tls-enabled = false + # certificate= "/etc/ssl/influxdb.pem" + + # Log an error for every malformed point. + # log-point-errors = true + + # These next lines control how batching works. You should have this enabled + # otherwise you could get dropped metrics or poor performance. Only points + # metrics received over the telnet protocol undergo batching. + + # Flush if this many points get buffered + # batch-size = 1000 + + # Number of batches that may be pending in memory + # batch-pending = 5 + + # Flush at least this often even if we haven't hit buffer limit + # batch-timeout = "1s" + +### +### [[udp]] +### +### Controls the listeners for InfluxDB line protocol data via UDP. +### + +[[udp]] + # enabled = false + # bind-address = ":8089" + # database = "udp" + # retention-policy = "" + + # InfluxDB precision for timestamps on received points ("" or "n", "u", "ms", "s", "m", "h") + # precision = "" + + # 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 + + # Will flush at least this often even if we haven't hit buffer limit + # batch-timeout = "1s" + + # UDP Read buffer size, 0 means OS default. UDP listener will fail if set above OS max. + # read-buffer = 0 + +### +### [continuous_queries] +### +### Controls how continuous queries are run within InfluxDB. +### + +[continuous_queries] + # Determines whether the continuous query service is enabled. + # enabled = true + + # Controls whether queries are logged when executed by the CQ service. + # log-enabled = true + + # Controls whether queries are logged to the self-monitoring data store. + # query-stats-enabled = false + + # interval for how often continuous queries will be checked if they need to run + # run-interval = "1s" + +### +### [tls] +### +### Global configuration settings for TLS in InfluxDB. +### + +[tls] + # Determines the available set of cipher suites. See https://golang.org/pkg/crypto/tls/#pkg-constants + # for a list of available ciphers, which depends on the version of Go (use the query + # SHOW DIAGNOSTICS to see the version of Go used to build InfluxDB). If not specified, uses + # the default settings from Go's crypto/tls package. + # ciphers = [ + # "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305", + # "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305", + # ] + + # Minimum version of the tls protocol that will be negotiated. If not specified, uses the + # default settings from Go's crypto/tls package. + # min-version = "tls1.2" + + # Maximum version of the tls protocol that will be negotiated. If not specified, uses the + # default settings from Go's crypto/tls package. + # max-version = "tls1.3" diff --git a/testing-modules/gatling-java/pom.xml b/testing-modules/gatling-java/pom.xml index 3f4bbe445d31..e8a803e7efd2 100644 --- a/testing-modules/gatling-java/pom.xml +++ b/testing-modules/gatling-java/pom.xml @@ -7,6 +7,7 @@ gatling-java 1.0-SNAPSHOT gatling-java + jar com.baeldung @@ -30,12 +31,28 @@ spring-boot-starter-web ${spring.version} + + org.springframework.boot + spring-boot-starter-actuator + ${spring.version} + + + io.micrometer + micrometer-registry-prometheus + 1.12.2 + org.projectlombok lombok ${lombok.version} provided + + ch.qos.logback + logback-classic + ${logback-classic.version} + runtime + com.github.javafaker javafaker @@ -67,6 +84,28 @@ true + + org.springframework.boot + spring-boot-maven-plugin + + org.baeldung.Application + gatling-java + io.gatling,io.gatling.highcharts + + + ch.qos.logback + logback-classic + + + + + + + repackage + + + + @@ -74,7 +113,7 @@ 3.9.5 4.3.0 1.0.2 - 2.7.5 + 2.7.18 + 1.3.10 - - \ No newline at end of file + diff --git a/testing-modules/gatling-java/prometheus/Dockerfile b/testing-modules/gatling-java/prometheus/Dockerfile new file mode 100644 index 000000000000..599a82b7a0fb --- /dev/null +++ b/testing-modules/gatling-java/prometheus/Dockerfile @@ -0,0 +1,5 @@ +FROM prom/prometheus:v2.48.1 + +COPY config/prometheus-docker.yml /etc/prometheus/prometheus.yml + +EXPOSE 9090:9090 diff --git a/testing-modules/gatling-java/prometheus/config/prometheus-docker.yml b/testing-modules/gatling-java/prometheus/config/prometheus-docker.yml new file mode 100644 index 000000000000..da5d77f7a3fa --- /dev/null +++ b/testing-modules/gatling-java/prometheus/config/prometheus-docker.yml @@ -0,0 +1,37 @@ +# my global config +global: + scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute. + evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute. + # scrape_timeout is set to the global default (10s). + +# Alertmanager configuration +alerting: + alertmanagers: + - static_configs: + - targets: + # - alertmanager:9093 + +# Load rules once and periodically evaluate them according to the global 'evaluation_interval'. +rule_files: +# - "first_rules.yml" +# - "second_rules.yml" + +# A scrape configuration containing exactly one endpoint to scrape: +# Here it's Prometheus itself. +scrape_configs: + # The job name is added as a label `job=` to any timeseries scraped from this config. + - job_name: 'prometheus' + # metrics_path defaults to '/metrics' + # scheme defaults to 'http'. + static_configs: + - targets: ['localhost:9090'] + - job_name: 'grafana' + scrape_interval: 5s + metrics_path: /metrics + static_configs: + - targets: ['grafana:3000'] + - job_name: 'service_metrics' + scrape_interval: 5s + metrics_path: /private/metrics + static_configs: + - targets: ['service:8080'] diff --git a/testing-modules/gatling-java/src/main/java/org/baeldung/PerformanceTestsController.java b/testing-modules/gatling-java/src/main/java/org/baeldung/PerformanceTestsController.java new file mode 100644 index 000000000000..dc38edfc73eb --- /dev/null +++ b/testing-modules/gatling-java/src/main/java/org/baeldung/PerformanceTestsController.java @@ -0,0 +1,30 @@ +package org.baeldung; + +import java.util.concurrent.ThreadLocalRandom; +import java.util.concurrent.TimeUnit; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@RestController +public class PerformanceTestsController { + + @GetMapping("/api/fast-response") + public ResponseEntity getFastResponse() { + return ResponseEntity.ok("was that fast enough?"); + } + + @GetMapping("/api/slow-response") + public ResponseEntity getSlowResponse() throws InterruptedException { + int min = 1000; + int max = 2000; + TimeUnit.MILLISECONDS.sleep(ThreadLocalRandom.current() + .nextInt(min, max)); + + return ResponseEntity.ok("this took a while"); + } +} diff --git a/testing-modules/gatling-java/src/main/resources/application.yml b/testing-modules/gatling-java/src/main/resources/application.yml new file mode 100644 index 000000000000..8438edc37e2e --- /dev/null +++ b/testing-modules/gatling-java/src/main/resources/application.yml @@ -0,0 +1,9 @@ +management: + endpoints: + web: + base-path: /private + exposure: + include: prometheus + exclude: metrics + path-mapping: + prometheus: metrics diff --git a/testing-modules/gatling-java/src/test/java/org/baeldung/FastEndpointSimulation.java b/testing-modules/gatling-java/src/test/java/org/baeldung/FastEndpointSimulation.java new file mode 100644 index 000000000000..1b24bcb55ab3 --- /dev/null +++ b/testing-modules/gatling-java/src/test/java/org/baeldung/FastEndpointSimulation.java @@ -0,0 +1,23 @@ +package org.baeldung; + +import static io.gatling.javaapi.core.CoreDsl.details; + +import io.gatling.javaapi.core.ChainBuilder; +import io.gatling.javaapi.core.PopulationBuilder; +import io.gatling.javaapi.core.Simulation; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class FastEndpointSimulation extends Simulation { + + public FastEndpointSimulation() { + ChainBuilder getFastEndpointChainBuilder = SimulationUtils.simpleGetRequest("request_fast_endpoint", "/api/fast-response", 200); + PopulationBuilder fastResponsesPopulationBuilder = SimulationUtils.buildScenario("getFastResponses", getFastEndpointChainBuilder, 200, 30, 180); + + setUp(fastResponsesPopulationBuilder) + .assertions( + details("request_fast_endpoint").successfulRequests().percent().gt(95.00), + details("request_fast_endpoint").responseTime().max().lte(10000) + ); + } +} diff --git a/testing-modules/gatling-java/src/test/java/org/baeldung/SimulationUtils.java b/testing-modules/gatling-java/src/test/java/org/baeldung/SimulationUtils.java new file mode 100644 index 000000000000..05f75b3b52d5 --- /dev/null +++ b/testing-modules/gatling-java/src/test/java/org/baeldung/SimulationUtils.java @@ -0,0 +1,55 @@ +package org.baeldung; + +import static io.gatling.javaapi.core.CoreDsl.bodyString; +import static io.gatling.javaapi.core.CoreDsl.constantUsersPerSec; +import static io.gatling.javaapi.core.CoreDsl.exec; +import static io.gatling.javaapi.core.CoreDsl.rampUsersPerSec; +import static io.gatling.javaapi.http.HttpDsl.http; +import static io.gatling.javaapi.http.HttpDsl.status; + +import io.gatling.javaapi.core.ChainBuilder; +import io.gatling.javaapi.core.CoreDsl; +import io.gatling.javaapi.core.PopulationBuilder; +import io.gatling.javaapi.core.Session; +import io.gatling.javaapi.http.HttpDsl; +import io.gatling.javaapi.http.HttpProtocolBuilder; +import io.gatling.javaapi.http.HttpRequestActionBuilder; + +public class SimulationUtils { + + private SimulationUtils() { + } + + public static PopulationBuilder buildScenario(String scenarioName, ChainBuilder request, double tps, int rampUpSeconds, int durationSeconds) { + return CoreDsl.scenario(scenarioName) + .exec(request) + .injectOpen(rampUsersPerSec(0).to(tps) + .during(rampUpSeconds), constantUsersPerSec(tps).during(durationSeconds - rampUpSeconds - rampUpSeconds), rampUsersPerSec(tps).to(0) + .during(rampUpSeconds)) + .protocols(getHttpProtocol()); + } + + public static ChainBuilder simpleGetRequest(String requestName, String requestPath, int expectedResponseStatus) { + HttpRequestActionBuilder request = http(requestName).get(requestPath) + .check(status().is(expectedResponseStatus)) + .check(bodyString().optional() + .saveAs("sBodyString")); + + return exec(Session::markAsSucceeded).exec(request) + .doIf(Session::isFailed) + .then(exec(session -> { + System.out.println("***Failure on [" + requestPath + "] endpoint:"); + System.out.print("Gatling Session Data: "); + System.out.println(session.getString("sBodyString")); + return session; + })); + } + + private static HttpProtocolBuilder getHttpProtocol() { + return HttpDsl.http.baseUrl("http://localhost:8080") + .acceptHeader("application/json") + .disableCaching() + .disableFollowRedirect() + .userAgentHeader("Gatling/Performance Test"); + } +} diff --git a/testing-modules/gatling-java/src/test/java/org/baeldung/SlowEndpointSimulation.java b/testing-modules/gatling-java/src/test/java/org/baeldung/SlowEndpointSimulation.java new file mode 100644 index 000000000000..9f212e9f3a88 --- /dev/null +++ b/testing-modules/gatling-java/src/test/java/org/baeldung/SlowEndpointSimulation.java @@ -0,0 +1,23 @@ +package org.baeldung; + +import static io.gatling.javaapi.core.CoreDsl.details; + +import io.gatling.javaapi.core.ChainBuilder; +import io.gatling.javaapi.core.PopulationBuilder; +import io.gatling.javaapi.core.Simulation; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class SlowEndpointSimulation extends Simulation { + + public SlowEndpointSimulation() { + ChainBuilder getSlowEndpointChainBuilder = SimulationUtils.simpleGetRequest("request_slow_endpoint", "/api/slow-response", 200); + PopulationBuilder slowResponsesPopulationBuilder = SimulationUtils.buildScenario("getSlowResponses", getSlowEndpointChainBuilder, 120, 30, 300); + + setUp(slowResponsesPopulationBuilder) + .assertions( + details("request_slow_endpoint").successfulRequests().percent().gt(95.00), + details("request_slow_endpoint").responseTime().max().lte(10000) + ); + } +} diff --git a/testing-modules/gatling-java/src/test/resources/gatling.conf b/testing-modules/gatling-java/src/test/resources/gatling.conf index 6ebfd6e820fa..34a5a5241f48 100644 --- a/testing-modules/gatling-java/src/test/resources/gatling.conf +++ b/testing-modules/gatling-java/src/test/resources/gatling.conf @@ -104,7 +104,7 @@ gatling { } } data { - #writers = [console, file] # The list of DataWriters to which Gatling write simulation data (currently supported : console, file, graphite, jdbc) + writers = [console, file, graphite] # The list of DataWriters to which Gatling write simulation data (currently supported : console, file, graphite, jdbc) console { #light = false # When set to true, displays a light version without detailed request stats } @@ -115,13 +115,13 @@ gatling { #noActivityTimeout = 30 # Period, in seconds, for which Gatling may have no activity before considering a leak may be happening } graphite { - #light = false # only send the all* stats - #host = "localhost" # The host where the Carbon server is located - #port = 2003 # The port to which the Carbon server listens to (2003 is default for plaintext, 2004 is default for pickle) - #protocol = "tcp" # The protocol used to send data to Carbon (currently supported : "tcp", "udp") - #rootPathPrefix = "gatling" # The common prefix of all metrics sent to Graphite - #bufferSize = 8192 # GraphiteDataWriter's internal data buffer size, in bytes - #writeInterval = 1 # GraphiteDataWriter's write interval, in seconds + light = false # only send the all* stats + host = "localhost" # The host where the Carbon server is located + port = 2003 # The port to which the Carbon server listens to (2003 is default for plaintext, 2004 is default for pickle) + protocol = "tcp" # The protocol used to send data to Carbon (currently supported : "tcp", "udp") + rootPathPrefix = "gatling" # The common prefix of all metrics sent to Graphite + bufferSize = 8192 # GraphiteDataWriter's internal data buffer size, in bytes + writePeriod = 1 # GraphiteDataWriter's write interval, in seconds } } }