From 3cbac7c1752fc0be22dc441c2d4eb6d6e20b6cbb Mon Sep 17 00:00:00 2001 From: AntonI Date: Sun, 25 Aug 2024 15:53:36 -0400 Subject: [PATCH] Upgrade to v0.53 and support with-browser Adds support for usage of k6 timescaledb with browser-based load testing. Adds modified dashboard sample tuned for k6 browser metrics --- Dockerfile | 31 +- go.mod | 23 +- ...grafana_dashboard_timescaledb_browser.json | 2727 +++++++++++++++++ 3 files changed, 2765 insertions(+), 16 deletions(-) create mode 100644 grafana/dashboards/grafana_dashboard_timescaledb_browser.json diff --git a/Dockerfile b/Dockerfile index fcd3556..414d072 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,16 +1,37 @@ -FROM golang:1.19-alpine as builder +FROM golang:1.23-alpine AS builder WORKDIR $GOPATH/src/go.k6.io/k6 ADD . . RUN apk --no-cache add git RUN CGO_ENABLED=0 go install go.k6.io/xk6/cmd/xk6@latest -RUN CGO_ENABLED=0 xk6 build --with github.com/grafana/xk6-output-timescaledb=. --output /tmp/k6 +RUN CGO_ENABLED=0 xk6 build v0.53.0 --with github.com/grafana/xk6-output-timescaledb=. --output /usr/bin/k6 + +FROM alpine:3.20.2 AS release -FROM alpine:3.16 RUN apk add --no-cache ca-certificates && \ adduser -D -u 12345 -g 12345 k6 -COPY --from=builder /tmp/k6 /usr/bin/k6 -USER 12345 +COPY --from=builder /usr/bin/k6 /usr/bin/k6 + +USER k6 WORKDIR /home/k6 ENTRYPOINT ["k6"] + +FROM release AS with-browser + +USER root + +COPY --from=release /usr/bin/k6 /usr/bin/k6 +RUN apk --no-cache add chromium-swiftshader + +USER k6 + +ENV CHROME_BIN=/usr/bin/chromium-browser +ENV CHROME_PATH=/usr/lib/chromium/ + +ENV K6_BROWSER_HEADLESS=true +# no-sandbox chrome arg is required to run chrome browser in +# alpine and avoids the usage of SYS_ADMIN Docker capability +ENV K6_BROWSER_ARGS=no-sandbox + +ENTRYPOINT ["k6"] diff --git a/go.mod b/go.mod index e5974b0..7d0cca7 100644 --- a/go.mod +++ b/go.mod @@ -1,18 +1,18 @@ module github.com/grafana/xk6-output-timescaledb -go 1.19 +go 1.20 require ( github.com/jackc/pgx/v5 v5.2.0 - github.com/sirupsen/logrus v1.9.0 - github.com/stretchr/testify v1.8.2 - go.k6.io/k6 v0.45.1 + github.com/sirupsen/logrus v1.9.3 + github.com/stretchr/testify v1.9.0 + go.k6.io/k6 v0.53.0 gopkg.in/guregu/null.v3 v3.3.0 ) require ( github.com/davecgh/go-spew v1.1.1 // indirect - github.com/fatih/color v1.15.0 // indirect + github.com/fatih/color v1.17.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b // indirect github.com/jackc/puddle/v2 v2.1.2 // indirect @@ -20,16 +20,17 @@ require ( github.com/kr/text v0.2.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.18 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/mstoykov/atlas v0.0.0-20220811071828-388f114305dd // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rogpeppe/go-internal v1.9.0 // indirect github.com/spf13/afero v1.1.2 // indirect go.uber.org/atomic v1.10.0 // indirect - golang.org/x/crypto v0.9.0 // indirect - golang.org/x/sync v0.2.0 // indirect - golang.org/x/sys v0.8.0 // indirect - golang.org/x/text v0.9.0 // indirect - golang.org/x/time v0.3.0 // indirect + golang.org/x/crypto v0.25.0 // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/crypto/ecdh v1.23.0 // indirect + golang.org/x/sys v0.22.0 // indirect + golang.org/x/text v0.16.0 // indirect + golang.org/x/time v0.5.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/grafana/dashboards/grafana_dashboard_timescaledb_browser.json b/grafana/dashboards/grafana_dashboard_timescaledb_browser.json new file mode 100644 index 0000000..ede339b --- /dev/null +++ b/grafana/dashboards/grafana_dashboard_timescaledb_browser.json @@ -0,0 +1,2727 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "target": { + "limit": 100, + "matchAny": false, + "tags": [], + "type": "dashboard" + }, + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": 3, + "links": [], + "liveNow": false, + "panels": [ + { + "datasource": { + "type": "postgres", + "uid": "PF9F4147845FC1E2E" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 8, + "x": 0, + "y": 0 + }, + "id": 4, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "none", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "10.0.2", + "targets": [ + { + "alias": "", + "datasource": { + "type": "postgres", + "uid": "PF9F4147845FC1E2E" + }, + "editorMode": "code", + "format": "time_series", + "group": [], + "metricColumn": "none", + "rawQuery": true, + "rawSql": "SELECT\n date_trunc('seconds', ts) AS \"time\",\n percentile_cont(0.95) WITHIN GROUP (ORDER BY value) AS \"success_95th_resp_time\"\nFROM\n samples\nWHERE\n $__timeFilter(ts)\n AND metric = 'browser_http_req_duration'\n AND (tags->>'status')::integer < 400\n AND (CASE WHEN $testid != '' THEN tags->>'testid' = $testid ELSE true END)\nGROUP BY 1\nORDER BY 1 ASC\n", + "refId": "A", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "column" + } + ] + ], + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + }, + "timeColumn": "time", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + } + ] + } + ], + "title": "Request duration (95th percentile)", + "type": "stat" + }, + { + "datasource": { + "type": "postgres", + "uid": "PF9F4147845FC1E2E" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 8, + "y": 0 + }, + "id": 5, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "none", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "10.0.2", + "targets": [ + { + "alias": "", + "datasource": { + "type": "postgres", + "uid": "PF9F4147845FC1E2E" + }, + "editorMode": "code", + "format": "time_series", + "group": [], + "metricColumn": "none", + "rawQuery": true, + "rawSql": "SELECT\n date_trunc('seconds', ts) AS \"time\",\n COUNT(value) AS \"reqs_per_sec\"\nFROM\n samples\nWHERE\n $__timeFilter(ts)\n AND metric = 'browser_http_req_duration'\n AND (CASE WHEN $testid != '' THEN tags->>'testid' = $testid ELSE true END)\nGROUP BY 1\nORDER BY 1 ASC", + "refId": "A", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "column" + } + ] + ], + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + }, + "timeColumn": "time", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + } + ] + } + ], + "title": "Requests/second", + "type": "stat" + }, + { + "datasource": { + "type": "postgres", + "uid": "PF9F4147845FC1E2E" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 12, + "y": 0 + }, + "id": 7, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "none", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "10.0.2", + "targets": [ + { + "alias": "", + "datasource": { + "type": "postgres", + "uid": "PF9F4147845FC1E2E" + }, + "editorMode": "code", + "format": "time_series", + "group": [], + "metricColumn": "none", + "rawQuery": true, + "rawSql": "SELECT \n\ttime,\n\tSUM(vus) as vus\nFROM (\n\tSELECT\n\t date_trunc('seconds', ts) AS \"time\",\n\t tags->>'replicaId' as \"instance\",\n\t MAX(value) AS \"vus\"\n\tFROM\n\t samples\n\tWHERE\n\t $__timeFilter(ts)\n AND metric = 'vus'\n\t AND (CASE WHEN $testid != '' THEN tags->>'testid' = $testid ELSE true END)\n\tGROUP BY 1, 2\n) AS max_vus_per_instance\ngroup by 1\nORDER BY 1 asc", + "refId": "A", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "column" + } + ] + ], + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + }, + "timeColumn": "time", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + } + ] + } + ], + "title": "Active VUs", + "type": "stat" + }, + { + "datasource": { + "type": "postgres", + "uid": "PF9F4147845FC1E2E" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 16, + "y": 0 + }, + "id": 6, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "none", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "mean" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "10.0.2", + "targets": [ + { + "alias": "", + "datasource": { + "type": "postgres", + "uid": "PF9F4147845FC1E2E" + }, + "editorMode": "code", + "format": "time_series", + "group": [], + "metricColumn": "none", + "rawQuery": true, + "rawSql": "SELECT\n 1 AS \"time\",\n COUNT(value)\nFROM\n samples\nWHERE\n metric = 'browser_http_req_duration'\n AND (tags->>'status')::int >= 400\n AND (CASE WHEN $testid != '' THEN tags->>'testid' = $testid ELSE true END)\nGROUP BY 1\nORDER BY 1 ASC", + "refId": "A", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "column" + } + ] + ], + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + }, + "timeColumn": "time", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + } + ] + } + ], + "title": "HTTP errors", + "type": "stat" + }, + { + "datasource": { + "type": "postgres", + "uid": "PF9F4147845FC1E2E" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 4, + "x": 20, + "y": 0 + }, + "id": 8, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "none", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "mean" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "10.0.2", + "targets": [ + { + "alias": "", + "datasource": { + "type": "postgres", + "uid": "PF9F4147845FC1E2E" + }, + "format": "time_series", + "group": [], + "metricColumn": "none", + "rawQuery": true, + "rawSql": "SELECT\n 1 AS \"time\",\n SUM(value)\nFROM\n samples\nWHERE\n metric = 'http_reqs'\n AND (tags->>'error_code')::int >= 1000\n AND (tags->>'error_code')::int <= 1399\n AND (CASE WHEN $testid != '' THEN tags->>'testid' = $testid ELSE true END)\nGROUP BY 1\nORDER BY 1 ASC", + "refId": "A", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "column" + } + ] + ], + "timeColumn": "time", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + } + ] + } + ], + "title": "Non-HTTP errors", + "type": "stat" + }, + { + "datasource": { + "type": "postgres", + "uid": "PF9F4147845FC1E2E" + }, + "description": "The 95th percentile response time of the target system, with success responses separated from error responses.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "links": [], + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "ms" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "failed" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "#890f02", + "mode": "fixed" + } + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 3 + }, + "id": 1, + "links": [], + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "8.2.6", + "targets": [ + { + "alias": "", + "datasource": { + "type": "postgres", + "uid": "PF9F4147845FC1E2E" + }, + "editorMode": "code", + "format": "time_series", + "group": [], + "metricColumn": "none", + "rawQuery": true, + "rawSql": "SELECT\n date_trunc('seconds', ts) AS \"time\",\n percentile_cont(0.95) WITHIN GROUP (ORDER BY value) AS \"successful\"\nFROM\n samples\nWHERE\n $__timeFilter(ts)\n AND metric = 'browser_http_req_duration'\n AND (tags->>'status')::integer < 400\n AND (CASE WHEN $testid != '' THEN tags->>'testid' = $testid ELSE true END)\nGROUP BY 1\nORDER BY 1 ASC\n", + "refId": "A", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "column" + } + ] + ], + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + }, + "timeColumn": "time", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + } + ] + }, + { + "alias": "", + "datasource": { + "type": "postgres", + "uid": "PF9F4147845FC1E2E" + }, + "editorMode": "code", + "format": "time_series", + "group": [], + "metricColumn": "none", + "rawQuery": true, + "rawSql": "SELECT\n date_trunc('seconds', ts) AS \"time\",\n percentile_cont(0.95) WITHIN GROUP (ORDER BY value) AS \"failed\"\nFROM\n samples\nWHERE\n $__timeFilter(ts)\n AND metric = 'browser_http_req_duration'\n AND (tags->>'status')::integer >= 400\n AND (CASE WHEN $testid != '' THEN tags->>'testid' = $testid ELSE true END)\nGROUP BY 1\nORDER BY 1 ASC\n", + "refId": "B", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "column" + } + ] + ], + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + }, + "timeColumn": "time", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + } + ] + } + ], + "title": "Request duration (95th percentile)", + "type": "timeseries" + }, + { + "datasource": { + "type": "postgres", + "uid": "PF9F4147845FC1E2E" + }, + "description": "Request rate, with successful responses separated from failed ones.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "links": [], + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "ops" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "error_reqs_per_sec" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "#890f02", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "vus" + }, + "properties": [ + { + "id": "unit", + "value": "short" + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 3 + }, + "id": 2, + "links": [], + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "8.2.6", + "targets": [ + { + "alias": "", + "datasource": { + "type": "postgres", + "uid": "PF9F4147845FC1E2E" + }, + "editorMode": "code", + "format": "time_series", + "group": [], + "metricColumn": "none", + "rawQuery": true, + "rawSql": "SELECT\n date_trunc('seconds', ts) AS \"time\",\n COUNT(value) AS \"reqs_per_sec\"\nFROM\n samples\nWHERE\n $__timeFilter(ts)\n AND metric = 'browser_http_req_duration'\n AND (CASE WHEN $testid != '' THEN tags->>'testid' = $testid ELSE true END)\nGROUP BY 1\nORDER BY 1 ASC", + "refId": "A", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "column" + } + ] + ], + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + }, + "timeColumn": "time", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + } + ] + }, + { + "alias": "", + "datasource": { + "type": "postgres", + "uid": "PF9F4147845FC1E2E" + }, + "editorMode": "code", + "format": "time_series", + "group": [], + "metricColumn": "none", + "rawQuery": true, + "rawSql": "SELECT \n\ttime,\n\tSUM(vus) as vus\nFROM (\n\tSELECT\n\t date_trunc('seconds', ts) AS \"time\",\n\t tags->>'replicaId' as \"instance\",\n\t MAX(value) AS \"vus\"\n\tFROM\n\t samples\n\tWHERE\n\t $__timeFilter(ts)\n AND metric = 'vus'\n\t AND (CASE WHEN $testid != '' THEN tags->>'testid' = $testid ELSE true END)\n\tGROUP BY 1, 2\n) AS max_vus_per_instance\ngroup by 1\nORDER BY 1 ASC", + "refId": "B", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "column" + } + ] + ], + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + }, + "timeColumn": "time", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + } + ] + } + ], + "title": "Throughput", + "type": "timeseries" + }, + { + "datasource": { + "type": "postgres", + "uid": "PF9F4147845FC1E2E" + }, + "description": "Failure rate.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "links": [], + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "percent" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "check_failure_rate" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "#c15c17", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "error_reqs_per_sec" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "#890f02", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "failure_rate" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "#890f02", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "http_failure_rate" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "#890f02", + "mode": "fixed" + } + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 3 + }, + "id": 3, + "links": [], + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "8.2.6", + "targets": [ + { + "alias": "", + "datasource": { + "type": "postgres", + "uid": "PF9F4147845FC1E2E" + }, + "format": "time_series", + "group": [], + "metricColumn": "none", + "rawQuery": true, + "rawSql": "SELECT\n date_trunc('seconds', ts) AS \"time\",\n SUM(CASE WHEN (tags->>'status')::int >= 400 THEN value ELSE 0 END)::real / SUM(value)::real * 100.0 AS \"http_failure_rate\"\nFROM\n samples\nWHERE\n $__timeFilter(ts)\n AND metric = 'http_reqs'\n AND (CASE WHEN $testid != '' THEN tags->>'testid' = $testid ELSE true END)\nGROUP BY 1\nORDER BY 1 ASC", + "refId": "B", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "column" + } + ] + ], + "timeColumn": "time", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + } + ] + }, + { + "alias": "", + "datasource": { + "type": "postgres", + "uid": "PF9F4147845FC1E2E" + }, + "format": "time_series", + "group": [], + "metricColumn": "none", + "rawQuery": true, + "rawSql": "SELECT\n date_trunc('seconds', ts) AS \"time\",\n CASE WHEN COUNT(value) > 0 THEN SUM(CASE WHEN value = 0 THEN 1 ELSE 0 END)::real / COUNT(value)::real * 100.0 ELSE 0 END AS \"check_failure_rate\"\nFROM\n samples\nWHERE\n $__timeFilter(ts)\n AND metric = 'checks'\n AND (CASE WHEN $testid != '' THEN tags->>'testid' = $testid ELSE true END)\nGROUP BY 1\nORDER BY 1 ASC", + "refId": "A", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "column" + } + ] + ], + "timeColumn": "time", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + } + ] + } + ], + "title": "Errors", + "type": "timeseries" + }, + { + "datasource": { + "type": "postgres", + "uid": "PF9F4147845FC1E2E" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "auto", + "cellOptions": { + "type": "auto" + }, + "inspect": false + }, + "mappings": [ + { + "options": { + "0": { + "index": 1, + "text": "fail" + }, + "1": { + "index": 0, + "text": "pass" + } + }, + "type": "value" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "pass_fail" + }, + "properties": [ + { + "id": "displayName", + "value": "pass/fail" + }, + { + "id": "unit", + "value": "short" + }, + { + "id": "custom.cellOptions", + "value": { + "mode": "gradient", + "type": "color-background" + } + }, + { + "id": "custom.align" + }, + { + "id": "thresholds", + "value": { + "mode": "absolute", + "steps": [ + { + "color": "rgba(245, 54, 54, 0.9)", + "value": null + }, + { + "color": "#F2495C", + "value": 0 + }, + { + "color": "rgba(50, 172, 45, 0.97)", + "value": 1 + } + ] + } + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 10 + }, + "id": 9, + "links": [], + "options": { + "cellHeight": "sm", + "footer": { + "countRows": false, + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "showHeader": true + }, + "pluginVersion": "10.0.2", + "targets": [ + { + "alias": "", + "datasource": { + "type": "postgres", + "uid": "PF9F4147845FC1E2E" + }, + "format": "table", + "group": [], + "metricColumn": "none", + "rawQuery": true, + "rawSql": "SELECT\n CASE WHEN \"tags\" IS NULL THEN \"metric\" ELSE \"metric\" || '{' || (SELECT key || ':' || value FROM jsonb_each_text(\"tags\")) || '}' END,\n \"threshold\",\n CASE WHEN \"last_failed\" THEN 0 ELSE 1 END AS pass_fail\nFROM\n thresholds\nWHERE\n $__timeFilter(ts)\nORDER BY 3 ASC\nLIMIT 100", + "refId": "A", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "column" + } + ] + ], + "timeColumn": "time", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + } + ] + } + ], + "title": "Thresholds", + "transformations": [ + { + "id": "merge", + "options": { + "reducers": [] + } + } + ], + "type": "table" + }, + { + "datasource": { + "type": "postgres", + "uid": "PF9F4147845FC1E2E" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "auto", + "cellOptions": { + "type": "auto" + }, + "inspect": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/failure_rate/" + }, + "properties": [ + { + "id": "unit", + "value": "percent" + }, + { + "id": "custom.cellOptions", + "value": { + "mode": "gradient", + "type": "color-background" + } + }, + { + "id": "custom.align" + }, + { + "id": "thresholds", + "value": { + "mode": "absolute", + "steps": [ + { + "color": "rgba(50, 172, 45, 0.97)", + "value": null + }, + { + "color": "rgba(237, 129, 40, 0.89)", + "value": 1 + }, + { + "color": "rgba(245, 54, 54, 0.9)", + "value": 1 + } + ] + } + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 10 + }, + "id": 13, + "links": [], + "options": { + "cellHeight": "sm", + "footer": { + "countRows": false, + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "showHeader": true + }, + "pluginVersion": "10.0.2", + "targets": [ + { + "alias": "", + "datasource": { + "type": "postgres", + "uid": "PF9F4147845FC1E2E" + }, + "format": "table", + "group": [], + "metricColumn": "none", + "rawQuery": true, + "rawSql": "SELECT\n tags->>'check' AS \"check\",\n SUM(CASE WHEN value = 1 THEN 1 ELSE 0 END) AS \"successful\",\n SUM(CASE WHEN value = 0 THEN 1 ELSE 0 END) AS \"failed\",\n CASE WHEN COUNT(value) > 0 THEN SUM(CASE WHEN value = 0 THEN 1 ELSE 0 END)::real / COUNT(value)::real * 100.0 ELSE 0 END AS \"failure_rate\"\nFROM\n samples\nWHERE\n $__timeFilter(ts)\n AND metric = 'checks'\n AND (CASE WHEN $testid != '' THEN tags->>'testid' = $testid ELSE true END)\nGROUP BY 1\nORDER BY 4 DESC\nLIMIT 100", + "refId": "A", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "column" + } + ] + ], + "timeColumn": "time", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + } + ] + } + ], + "title": "Checks with highest failure rate", + "transformations": [ + { + "id": "merge", + "options": { + "reducers": [] + } + } + ], + "type": "table" + }, + { + "datasource": { + "type": "postgres", + "uid": "PF9F4147845FC1E2E" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "auto", + "cellOptions": { + "type": "auto" + }, + "inspect": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": "/max|([0-9]{2}th)/" + }, + "properties": [ + { + "id": "unit", + "value": "ms" + }, + { + "id": "custom.align" + }, + { + "id": "thresholds", + "value": { + "mode": "absolute", + "steps": [ + { + "color": "rgba(50, 172, 45, 0.97)", + "value": null + }, + { + "color": "rgba(237, 129, 40, 0.89)", + "value": 500 + }, + { + "color": "rgba(245, 54, 54, 0.9)", + "value": 1000 + } + ] + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "URL" + }, + "properties": [ + { + "id": "unit", + "value": "short" + }, + { + "id": "decimals", + "value": 2 + }, + { + "id": "links", + "value": [ + { + "targetBlank": true, + "title": "Click to open $__cell in new tab", + "url": "$__cell" + } + ] + }, + { + "id": "custom.align" + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 17 + }, + "id": 10, + "links": [], + "options": { + "cellHeight": "sm", + "footer": { + "countRows": false, + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "showHeader": true + }, + "pluginVersion": "10.0.2", + "targets": [ + { + "alias": "", + "datasource": { + "type": "postgres", + "uid": "PF9F4147845FC1E2E" + }, + "editorMode": "code", + "format": "table", + "group": [], + "metricColumn": "none", + "rawQuery": true, + "rawSql": "SELECT\n tags->>'url' AS \"URL\",\n tags->>'method' AS \"method\",\n CASE \n WHEN (tags->>'status')::int = 0 AND (tags->>'error_code')::int >= 1000 AND (tags->>'error_code')::int <= 1099 THEN tags->>'error_code' || ' (General)'\n WHEN (tags->>'status')::int = 0 AND (tags->>'error_code')::int = 1101 THEN tags->>'error_code' || ' (DNS no such host)'\n WHEN (tags->>'status')::int = 0 AND (tags->>'error_code')::int = 1110 THEN tags->>'error_code' || ' (DNS blacklisted IP)'\n WHEN (tags->>'status')::int = 0 AND (tags->>'error_code')::int >= 1100 AND (tags->>'error_code')::int <= 1199 THEN tags->>'error_code' || ' (DNS)'\n WHEN (tags->>'status')::int = 0 AND (tags->>'error_code')::int = 1211 THEN tags->>'error_code' || ' (TCP connection timeout)'\n WHEN (tags->>'status')::int = 0 AND (tags->>'error_code')::int = 1212 THEN tags->>'error_code' || ' (TCP connection refused)'\n WHEN (tags->>'status')::int = 0 AND (tags->>'error_code')::int = 1213 THEN tags->>'error_code' || ' (TCP connection error)'\n WHEN (tags->>'status')::int = 0 AND (tags->>'error_code')::int >= 1200 AND (tags->>'error_code')::int <= 1299 THEN tags->>'error_code' || ' (TCP)'\n WHEN (tags->>'status')::int = 0 AND (tags->>'error_code')::int = 1311 THEN tags->>'error_code' || ' (TLS cert not matching hostname)'\n WHEN (tags->>'status')::int = 0 AND (tags->>'error_code')::int >= 1300 AND (tags->>'error_code')::int <= 1399 THEN tags->>'error_code' || ' (TLS)'\n WHEN (tags->>'status')::int = 0 AND (tags->>'error_code')::int >= 1600 AND (tags->>'error_code')::int <= 1699 THEN tags->>'error_code' || ' (HTTP/2)'\n WHEN (tags->>'status')::int = 0 THEN tags->>'error_code'\n ELSE tags->>'status'\n END AS \"status\",\n COUNT(*) AS count,\n percentile_cont(0.95) WITHIN GROUP (ORDER BY value) AS \"95th\",\n percentile_cont(0.99) WITHIN GROUP (ORDER BY value) AS \"99th\",\n MAX(value) AS \"max\"\nFROM\n samples\nWHERE\n $__timeFilter(ts)\n AND metric = 'browser_http_req_duration'\n AND (CASE WHEN $testid != '' THEN tags->>'testid' = $testid ELSE true END)\nGROUP BY 1, 2, 3\nORDER BY 6 DESC\nLIMIT 100", + "refId": "A", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "column" + } + ] + ], + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + }, + "timeColumn": "time", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + } + ] + } + ], + "title": "URLs", + "transformations": [ + { + "id": "merge", + "options": { + "reducers": [] + } + } + ], + "type": "table" + }, + { + "datasource": { + "type": "postgres", + "uid": "PF9F4147845FC1E2E" + }, + "description": "Breakdown of web vitals while performing load test", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "links": [], + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "ms" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 24 + }, + "id": 11, + "links": [], + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "8.2.6", + "targets": [ + { + "alias": "", + "datasource": { + "type": "postgres", + "uid": "PF9F4147845FC1E2E" + }, + "editorMode": "code", + "format": "time_series", + "group": [], + "metricColumn": "none", + "rawQuery": true, + "rawSql": "SELECT\n date_trunc('seconds', ts) AS \"time\",\n percentile_cont(0.95) WITHIN GROUP (ORDER BY value) AS \"lcp (Largest Contentful Paint)\"\nFROM\n samples\nWHERE\n $__timeFilter(ts)\n AND metric = 'browser_web_vital_lcp'\n AND (CASE WHEN $testid != '' THEN tags->>'testid' = $testid ELSE true END)\nGROUP BY 1\nORDER BY 1 ASC\n", + "refId": "A", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "column" + } + ] + ], + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + }, + "timeColumn": "time", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + } + ] + }, + { + "alias": "", + "datasource": { + "type": "postgres", + "uid": "PF9F4147845FC1E2E" + }, + "editorMode": "code", + "format": "time_series", + "group": [], + "metricColumn": "none", + "rawQuery": true, + "rawSql": "SELECT\n date_trunc('seconds', ts) AS \"time\",\n percentile_cont(0.95) WITHIN GROUP (ORDER BY value) AS \"inp (Interaction to Next Paint)\"\nFROM\n samples\nWHERE\n $__timeFilter(ts)\n AND metric = 'browser_web_vital_inp'\n AND (CASE WHEN $testid != '' THEN tags->>'testid' = $testid ELSE true END)\nGROUP BY 1\nORDER BY 1 ASC\n", + "refId": "E", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "column" + } + ] + ], + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + }, + "timeColumn": "time", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + } + ] + }, + { + "alias": "", + "datasource": { + "type": "postgres", + "uid": "PF9F4147845FC1E2E" + }, + "editorMode": "code", + "format": "time_series", + "group": [], + "metricColumn": "none", + "rawQuery": true, + "rawSql": "SELECT\n date_trunc('seconds', ts) AS \"time\",\n percentile_cont(0.95) WITHIN GROUP (ORDER BY value) AS \"cls (Cumulative Layout Shift)\"\nFROM\n samples\nWHERE\n $__timeFilter(ts)\n AND metric = 'browser_web_vital_cls'\n AND (CASE WHEN $testid != '' THEN tags->>'testid' = $testid ELSE true END)\nGROUP BY 1\nORDER BY 1 ASC\n", + "refId": "F", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "column" + } + ] + ], + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + }, + "timeColumn": "time", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + } + ] + }, + { + "alias": "", + "datasource": { + "type": "postgres", + "uid": "PF9F4147845FC1E2E" + }, + "editorMode": "code", + "format": "time_series", + "group": [], + "metricColumn": "none", + "rawQuery": true, + "rawSql": "SELECT\n date_trunc('seconds', ts) AS \"time\",\n percentile_cont(0.95) WITHIN GROUP (ORDER BY value) AS \"fid (First Input Delay)\"\nFROM\n samples\nWHERE\n $__timeFilter(ts)\n AND metric = 'browser_web_vital_fid'\n AND (CASE WHEN $testid != '' THEN tags->>'testid' = $testid ELSE true END)\nGROUP BY 1\nORDER BY 1 ASC\n", + "refId": "B", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "column" + } + ] + ], + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + }, + "timeColumn": "time", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + } + ] + }, + { + "alias": "", + "datasource": { + "type": "postgres", + "uid": "PF9F4147845FC1E2E" + }, + "editorMode": "code", + "format": "time_series", + "group": [], + "metricColumn": "none", + "rawQuery": true, + "rawSql": "SELECT\n date_trunc('seconds', ts) AS \"time\",\n percentile_cont(0.95) WITHIN GROUP (ORDER BY value) AS \"fcp (First Contentful Paint)\"\nFROM\n samples\nWHERE\n $__timeFilter(ts)\n AND metric = 'browser_web_vital_fcp'\n AND (CASE WHEN $testid != '' THEN tags->>'testid' = $testid ELSE true END)\nGROUP BY 1\nORDER BY 1 ASC\n", + "refId": "C", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "column" + } + ] + ], + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + }, + "timeColumn": "time", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + } + ] + }, + { + "alias": "", + "datasource": { + "type": "postgres", + "uid": "PF9F4147845FC1E2E" + }, + "editorMode": "code", + "format": "time_series", + "group": [], + "metricColumn": "none", + "rawQuery": true, + "rawSql": "SELECT\n date_trunc('seconds', ts) AS \"time\",\n percentile_cont(0.95) WITHIN GROUP (ORDER BY value) AS \"ttfb (Time To First Byte)\"\nFROM\n samples\nWHERE\n $__timeFilter(ts)\n AND metric = 'browser_web_vital_ttfb'\n AND (CASE WHEN $testid != '' THEN tags->>'testid' = $testid ELSE true END)\nGROUP BY 1\nORDER BY 1 ASC\n", + "refId": "D", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "column" + } + ] + ], + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + }, + "timeColumn": "time", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + } + ] + } + ], + "title": "Web Vitals (95th percentile)", + "type": "timeseries" + }, + { + "datasource": { + "type": "postgres", + "uid": "PF9F4147845FC1E2E" + }, + "description": "Trend of observed poor vitals", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "links": [], + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "ops" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "error_reqs_per_sec" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "#890f02", + "mode": "fixed" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "vus" + }, + "properties": [ + { + "id": "unit", + "value": "short" + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 24 + }, + "id": 14, + "links": [], + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "8.2.6", + "targets": [ + { + "alias": "", + "datasource": { + "type": "postgres", + "uid": "PF9F4147845FC1E2E" + }, + "editorMode": "code", + "format": "time_series", + "group": [], + "metricColumn": "none", + "rawQuery": true, + "rawSql": "SELECT\n date_trunc('seconds', ts) AS \"time\",\n COUNT(value) AS \"poor_vitals_per_sec\"\nFROM\n samples\nWHERE\n $__timeFilter(ts)\n AND starts_with(metric, 'browser_web_vital_')\n AND tags->>'rating' = 'poor'\n AND (CASE WHEN $testid != '' THEN tags->>'testid' = $testid ELSE true END)\nGROUP BY 1\nORDER BY 1 ASC", + "refId": "A", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "column" + } + ] + ], + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + }, + "timeColumn": "time", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + } + ] + }, + { + "alias": "", + "datasource": { + "type": "postgres", + "uid": "PF9F4147845FC1E2E" + }, + "editorMode": "code", + "format": "time_series", + "group": [], + "hide": false, + "metricColumn": "none", + "rawQuery": true, + "rawSql": "SELECT\n date_trunc('seconds', ts) AS \"time\",\n COUNT(value) AS \"all_requests\"\nFROM\n samples\nWHERE\n $__timeFilter(ts)\n AND metric = 'browser_http_req_duration'\n AND (CASE WHEN $testid != '' THEN tags->>'testid' = $testid ELSE true END)\nGROUP BY 1\nORDER BY 1 ASC", + "refId": "B", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "column" + } + ] + ], + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + }, + "timeColumn": "time", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + } + ] + } + ], + "title": "Poor vitals", + "type": "timeseries" + }, + { + "datasource": { + "type": "postgres", + "uid": "PF9F4147845FC1E2E" + }, + "description": "Data sent and received per second.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "links": [], + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "Bps" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "data_sent" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "#64b0c8", + "mode": "fixed" + } + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 31 + }, + "id": 12, + "links": [], + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "8.2.6", + "targets": [ + { + "alias": "", + "datasource": { + "type": "postgres", + "uid": "PF9F4147845FC1E2E" + }, + "format": "time_series", + "group": [], + "metricColumn": "none", + "rawQuery": true, + "rawSql": "SELECT\n date_trunc('seconds', ts) AS \"time\",\n SUM(value) AS \"data_sent\"\nFROM\n samples\nWHERE\n $__timeFilter(ts)\n AND metric = 'data_sent'\n AND (CASE WHEN $testid != '' THEN tags->>'testid' = $testid ELSE true END)\nGROUP BY 1\nORDER BY 1 ASC", + "refId": "A", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "column" + } + ] + ], + "timeColumn": "time", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + } + ] + }, + { + "alias": "", + "datasource": { + "type": "postgres", + "uid": "PF9F4147845FC1E2E" + }, + "format": "time_series", + "group": [], + "metricColumn": "none", + "rawQuery": true, + "rawSql": "SELECT\n date_trunc('seconds', ts) AS \"time\",\n SUM(value) AS \"data_received\"\nFROM\n samples\nWHERE\n $__timeFilter(ts)\n AND metric = 'data_received'\n AND (CASE WHEN $testid != '' THEN tags->>'testid' = $testid ELSE true END)\nGROUP BY 1\nORDER BY 1 ASC", + "refId": "B", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "column" + } + ] + ], + "timeColumn": "time", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + } + ] + } + ], + "title": "Data transfer", + "type": "timeseries" + }, + { + "datasource": { + "type": "postgres", + "uid": "PF9F4147845FC1E2E" + }, + "description": "The 95th percentile response time of the target system, with success responses separated from error responses.", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "links": [], + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "ms" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "failed" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "#890f02", + "mode": "fixed" + } + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 31 + }, + "id": 15, + "links": [], + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "8.2.6", + "targets": [ + { + "alias": "", + "datasource": { + "type": "postgres", + "uid": "PF9F4147845FC1E2E" + }, + "editorMode": "code", + "format": "time_series", + "group": [], + "metricColumn": "none", + "rawQuery": true, + "rawSql": "SELECT\n date_trunc('seconds', ts) AS \"time\",\n percentile_cont(0.95) WITHIN GROUP (ORDER BY value) AS \"duration\"\nFROM\n samples\nWHERE\n $__timeFilter(ts)\n AND metric = 'iteration_duration'\n AND (CASE WHEN $testid != '' THEN tags->>'testid' = $testid ELSE true END)\nGROUP BY 1\nORDER BY 1 ASC\n", + "refId": "A", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "column" + } + ] + ], + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + }, + "timeColumn": "time", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + } + ] + }, + { + "alias": "", + "datasource": { + "type": "postgres", + "uid": "PF9F4147845FC1E2E" + }, + "editorMode": "code", + "format": "time_series", + "group": [], + "metricColumn": "none", + "rawQuery": true, + "rawSql": "SELECT\n date_trunc('seconds', ts) AS \"time\",\n percentile_cont(0.95) WITHIN GROUP (ORDER BY value) AS \"failed\"\nFROM\n samples\nWHERE\n $__timeFilter(ts)\n AND metric = 'browser_http_req_duration'\n AND (tags->>'status')::integer >= 400\n AND (CASE WHEN $testid != '' THEN tags->>'testid' = $testid ELSE true END)\nGROUP BY 1\nORDER BY 1 ASC\n", + "refId": "B", + "select": [ + [ + { + "params": [ + "value" + ], + "type": "column" + } + ] + ], + "sql": { + "columns": [ + { + "parameters": [], + "type": "function" + } + ], + "groupBy": [ + { + "property": { + "type": "string" + }, + "type": "groupBy" + } + ], + "limit": 50 + }, + "timeColumn": "time", + "where": [ + { + "name": "$__timeFilter", + "params": [], + "type": "macro" + } + ] + } + ], + "title": "Iteration duration (95th percentile)", + "type": "timeseries" + } + ], + "refresh": "", + "schemaVersion": 38, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "allValue": "''", + "current": { + "selected": false, + "text": "All", + "value": "$__all" + }, + "datasource": { + "type": "postgres", + "uid": "PF9F4147845FC1E2E" + }, + "definition": "", + "hide": 0, + "includeAll": true, + "label": "Test ID", + "multi": false, + "name": "testid", + "options": [], + "query": "SELECT DISTINCT tags->>'testid' AS \"id\" FROM samples WHERE metric = 'vus';", + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 1, + "tagValuesQuery": "", + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "", + "title": "Open Source Browser Load Testing Stack", + "uid": "afc54dbe-42ec-4bff-a145-e1122b6b6ad3", + "version": 17, + "weekStart": "" +} \ No newline at end of file