diff --git a/Dockerfile b/Dockerfile index 7b508ef..e922f42 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,28 +1,24 @@ FROM python:3.8-slim-buster - -LABEL maintainer="Josh Smith" \ +LABEL maintainer="Team QLUSTOR " \ description="Original by Aiden Gilmartin. Speedtest to InfluxDB data bridge" -# Install dependencies ENV DEBIAN_FRONTEND=noninteractive -RUN apt-get update -RUN apt-get -q -y install --no-install-recommends apt-utils gnupg1 apt-transport-https dirmngr - -# Install speedtest-cli -RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 379CE192D401AB61 -RUN echo "deb https://ookla.bintray.com/debian buster main" | tee /etc/apt/sources.list.d/speedtest.list -RUN apt-get update && apt-get -q -y install speedtest +RUN true &&\ +\ +# Install dependencies +apt-get update && \ +apt-get -q -y install --no-install-recommends apt-utils gnupg1 apt-transport-https dirmngr && \ +\ # Install Python packages -COPY requirements.txt / -RUN pip install -r /requirements.txt - +pip3 install pythonping influxdb && \ +\ # Clean up -RUN apt-get -q -y autoremove -RUN apt-get -q -y clean -RUN rm -rf /var/lib/apt/lists/* +apt-get -q -y autoremove && apt-get -q -y clean && \ +rm -rf /var/lib/apt/lists/* # Final setup & execution -COPY . /app +ADD . /app WORKDIR /app -CMD ["python3", "-u", "main.py"] \ No newline at end of file +ENTRYPOINT ["/bin/sh", "/app/entrypoint.sh"] +CMD ["main.py"] diff --git a/GrafanaDash-SpeedTests.json b/GrafanaDash-SpeedTests.json new file mode 100644 index 0000000..cc0749c --- /dev/null +++ b/GrafanaDash-SpeedTests.json @@ -0,0 +1,3002 @@ +{ + "__inputs": [ + { + "name": "DS_INFLUXDB-SPEEDTESTS", + "label": "InfluxDB-speedtests", + "description": "", + "type": "datasource", + "pluginId": "influxdb", + "pluginName": "InfluxDB" + } + ], + "__requires": [ + { + "type": "grafana", + "id": "grafana", + "name": "Grafana", + "version": "7.3.6" + }, + { + "type": "panel", + "id": "graph", + "name": "Graph", + "version": "" + }, + { + "type": "datasource", + "id": "influxdb", + "name": "InfluxDB", + "version": "1.0.0" + }, + { + "type": "panel", + "id": "stat", + "name": "Stat", + "version": "" + }, + { + "type": "panel", + "id": "table", + "name": "Table", + "version": "" + } + ], + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "description": "A dashboard to display speedtest data over time.", + "editable": true, + "gnetId": 13053, + "graphTooltip": 0, + "id": null, + "iteration": 1611279295418, + "links": [], + "panels": [ + { + "datasource": "${DS_INFLUXDB-SPEEDTESTS}", + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "semi-dark-blue", + "mode": "fixed" + }, + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "red", + "value": null + }, + { + "color": "light-yellow", + "value": 700 + }, + { + "color": "green", + "value": 825 + } + ] + }, + "unit": "Mbits" + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 3, + "x": 0, + "y": 0 + }, + "id": 116, + "interval": "5m", + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "mean" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "pluginVersion": "7.3.6", + "targets": [ + { + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + } + ], + "measurement": "download", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "bandwidth" + ], + "type": "field" + }, + { + "params": [], + "type": "last" + } + ] + ], + "tags": [ + { + "key": "namespace", + "operator": "=~", + "value": "/^$namespace$/" + } + ] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Avg Download Speed", + "type": "stat" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_INFLUXDB-SPEEDTESTS}", + "description": "Uses https://github.com/breadlysm/speedtest-to-influxdb", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 3, + "gridPos": { + "h": 7, + "w": 18, + "x": 3, + "y": 0 + }, + "hiddenSeries": false, + "id": 104, + "interval": "", + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "connected", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.6", + "pointradius": 0.5, + "points": true, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "Upload", + "color": "#A352CC" + }, + { + "alias": "Download", + "color": "#3274D9" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "Download", + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + } + ], + "measurement": "download", + "orderByTime": "ASC", + "policy": "default", + "query": "SELECT mean(\"bytes\") FROM \"download\" WHERE $timeFilter GROUP BY time($__interval) fill(0)", + "rawQuery": false, + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "bandwidth" + ], + "type": "field" + }, + { + "params": [], + "type": "last" + } + ] + ], + "tags": [ + { + "key": "namespace", + "operator": "=~", + "value": "/^$namespace$/" + } + ] + }, + { + "alias": "Upload", + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + } + ], + "measurement": "upload", + "orderByTime": "ASC", + "policy": "default", + "query": "SELECT mean(\"bytes\") FROM \"download\" WHERE $timeFilter GROUP BY time($__interval) fill(0)", + "rawQuery": false, + "refId": "B", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "bandwidth" + ], + "type": "field" + }, + { + "params": [], + "type": "last" + } + ] + ], + "tags": [ + { + "key": "namespace", + "operator": "=~", + "value": "/^$namespace$/" + } + ] + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Speedtest Results", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "Mbits", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "datasource": "${DS_INFLUXDB-SPEEDTESTS}", + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "semi-dark-yellow", + "mode": "fixed" + }, + "custom": {}, + "decimals": 2, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "yellow", + "value": 10000 + }, + { + "color": "red", + "value": 14000 + } + ] + }, + "unit": "ms" + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 21, + "y": 0 + }, + "id": 122, + "interval": "5m", + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "mean" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "pluginVersion": "7.3.6", + "targets": [ + { + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + } + ], + "measurement": "download", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "elapsed" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [ + { + "key": "namespace", + "operator": "=~", + "value": "/^$namespace$/" + } + ] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Avg Test Time", + "type": "stat" + }, + { + "datasource": "${DS_INFLUXDB-SPEEDTESTS}", + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "semi-dark-purple", + "mode": "fixed" + }, + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "red", + "value": null + }, + { + "color": "light-yellow", + "value": 700 + }, + { + "color": "green", + "value": 825 + } + ] + }, + "unit": "Mbits" + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 3, + "x": 0, + "y": 2 + }, + "id": 118, + "interval": "5m", + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "mean" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "pluginVersion": "7.3.6", + "targets": [ + { + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + } + ], + "measurement": "upload", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "bandwidth" + ], + "type": "field" + }, + { + "params": [], + "type": "last" + } + ] + ], + "tags": [ + { + "key": "namespace", + "operator": "=~", + "value": "/^$namespace$/" + } + ] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Avg Upload Speed", + "type": "stat" + }, + { + "datasource": "${DS_INFLUXDB-SPEEDTESTS}", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "decbytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 3, + "x": 21, + "y": 3 + }, + "id": 124, + "interval": "5m", + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "sum" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "pluginVersion": "7.3.6", + "targets": [ + { + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + } + ], + "measurement": "download", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "bytes" + ], + "type": "field" + }, + { + "params": [], + "type": "last" + } + ] + ], + "tags": [ + { + "key": "namespace", + "operator": "=~", + "value": "/^$namespace$/" + } + ] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Total Test Downloaded", + "type": "stat" + }, + { + "datasource": "${DS_INFLUXDB-SPEEDTESTS}", + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "semi-dark-yellow", + "mode": "fixed" + }, + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "#EAB839", + "value": 90 + }, + { + "color": "red", + "value": 150 + } + ] + }, + "unit": "ms" + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 0, + "y": 4 + }, + "id": 120, + "interval": "5m", + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "mean" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "pluginVersion": "7.3.6", + "targets": [ + { + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + } + ], + "measurement": "ping", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "latency" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [ + { + "key": "namespace", + "operator": "=~", + "value": "/^$namespace$/" + } + ] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Avg Test Latency", + "type": "stat" + }, + { + "datasource": "${DS_INFLUXDB-SPEEDTESTS}", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "decbytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 2, + "w": 3, + "x": 21, + "y": 5 + }, + "id": 125, + "interval": "5m", + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "sum" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "pluginVersion": "7.3.6", + "targets": [ + { + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + } + ], + "measurement": "upload", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "bytes" + ], + "type": "field" + }, + { + "params": [], + "type": "last" + } + ] + ], + "tags": [ + { + "key": "namespace", + "operator": "=~", + "value": "/^$namespace$/" + } + ] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Total Test Uploaded", + "type": "stat" + }, + { + "datasource": "${DS_INFLUXDB-SPEEDTESTS}", + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "dark-green", + "mode": "fixed" + }, + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "percentunit" + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 0, + "y": 7 + }, + "id": 139, + "interval": "5s", + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "mean" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "pluginVersion": "7.3.6", + "targets": [ + { + "groupBy": [ + { + "params": [ + "$interval" + ], + "type": "time" + } + ], + "measurement": "pings", + "orderByTime": "ASC", + "policy": "default", + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "success" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [ + { + "key": "namespace", + "operator": "=~", + "value": "/^$namespace$/" + } + ], + "tz": "" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Uptime", + "type": "stat" + }, + { + "aliasColors": { + "Latency": "semi-dark-yellow", + "Uptime": "dark-green", + "pings.min": "light-green", + "pings.sucess": "dark-green" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_INFLUXDB-SPEEDTESTS}", + "description": "", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 3, + "gridPos": { + "h": 6, + "w": 21, + "x": 3, + "y": 7 + }, + "hiddenSeries": false, + "id": 138, + "interval": "", + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": true, + "min": true, + "rightSide": true, + "show": true, + "sideWidth": 180, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "connected", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.3.6", + "pointradius": 0.5, + "points": true, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "pings.min", + "yaxis": 2 + }, + { + "alias": "pings.sucess", + "yaxis": 2 + }, + { + "alias": "Uptime", + "yaxis": 2 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "alias": "Uptime", + "groupBy": [ + { + "params": [ + "$interval" + ], + "type": "time" + } + ], + "measurement": "pings", + "orderByTime": "ASC", + "policy": "default", + "query": "SELECT mean(\"bytes\") FROM \"download\" WHERE $timeFilter GROUP BY time($__interval) fill(0)", + "rawQuery": false, + "refId": "B", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "success" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [ + { + "key": "namespace", + "operator": "=~", + "value": "/^$namespace$/" + } + ], + "tz": "" + }, + { + "alias": "Latency", + "groupBy": [ + { + "params": [ + "$interval" + ], + "type": "time" + } + ], + "measurement": "pings", + "orderByTime": "ASC", + "policy": "default", + "query": "SELECT mean(\"rtt\") FROM \"pings\" WHERE (\"namespace\" =~ /^$namespace$/) AND success = 1 AND $timeFilter GROUP BY time($interval)", + "rawQuery": true, + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "rtt" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [ + { + "key": "namespace", + "operator": "=~", + "value": "/^$namespace$/" + } + ] + }, + { + "alias": "", + "groupBy": [ + { + "params": [ + "$interval" + ], + "type": "time" + }, + { + "params": [ + "target" + ], + "type": "tag" + } + ], + "hide": true, + "measurement": "pings", + "orderByTime": "ASC", + "policy": "autogen", + "query": "SELECT mean(\"rtt\") AS \"Latency\" FROM \"pings\" WHERE (\"namespace\" =~ /^$namespace$/) AND success = 1 AND $timeFilter GROUP BY time($interval), \"target\"", + "rawQuery": true, + "refId": "C", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "rtt" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + }, + { + "params": [ + "Latency" + ], + "type": "alias" + } + ] + ], + "tags": [ + { + "key": "namespace", + "operator": "=~", + "value": "/^$namespace$/" + } + ] + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "High Frequency Ping Results", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": null, + "format": "ms", + "label": null, + "logBase": 2, + "max": "256", + "min": "4", + "show": true + }, + { + "decimals": null, + "format": "percentunit", + "label": "", + "logBase": 1, + "max": "1", + "min": "0", + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "datasource": "${DS_INFLUXDB-SPEEDTESTS}", + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "semi-dark-yellow", + "mode": "fixed" + }, + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "yellow", + "value": 90 + }, + { + "color": "red", + "value": 150 + } + ] + }, + "unit": "ms" + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 3, + "x": 0, + "y": 10 + }, + "id": 140, + "interval": "5s", + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "mean" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "pluginVersion": "7.3.6", + "targets": [ + { + "groupBy": [ + { + "params": [ + "$__interval" + ], + "type": "time" + } + ], + "measurement": "pings", + "orderByTime": "ASC", + "policy": "default", + "query": "SELECT mean(\"rtt\") FROM \"pings\" WHERE (\"namespace\" =~ /^$namespace$/) AND success = 1 AND $timeFilter GROUP BY time($__interval)", + "rawQuery": true, + "refId": "A", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "rtt" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [ + { + "key": "namespace", + "operator": "=~", + "value": "/^$namespace$/" + } + ] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Avg Ping Latency", + "type": "stat" + }, + { + "collapsed": false, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 13 + }, + "id": 137, + "panels": [], + "title": "Leaders (Green) & Laggers (Yellow)", + "type": "row" + }, + { + "datasource": "${DS_INFLUXDB-SPEEDTESTS}", + "description": "", + "fieldConfig": { + "defaults": { + "custom": { + "align": "center", + "filterable": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Time" + }, + "properties": [ + { + "id": "custom.width", + "value": 175 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "SPEEDTEST.net URL" + }, + "properties": [ + { + "id": "custom.width", + "value": 525 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Down Mbps" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-green", + "mode": "fixed" + } + }, + { + "id": "custom.displayMode", + "value": "color-background" + } + ] + } + ] + }, + "gridPos": { + "h": 3, + "w": 24, + "x": 0, + "y": 14 + }, + "id": 127, + "options": { + "frameIndex": 0, + "showHeader": true, + "sortBy": [] + }, + "pluginVersion": "7.3.6", + "targets": [ + { + "groupBy": [], + "hide": false, + "measurement": "download", + "orderByTime": "ASC", + "policy": "default", + "query": "SELECT max(\"bandwidth\") AS \"Down Mbps\" FROM \"download\" WHERE (\"namespace\" =~ /^$namespace$/) AND $timeFilter", + "rawQuery": false, + "refId": "B", + "resultFormat": "table", + "select": [ + [ + { + "params": [ + "bandwidth" + ], + "type": "field" + }, + { + "params": [], + "type": "max" + }, + { + "params": [ + "Down Mbps" + ], + "type": "alias" + } + ] + ], + "tags": [ + { + "key": "namespace", + "operator": "=~", + "value": "/^$namespace$/" + } + ] + }, + { + "groupBy": [ + { + "params": [ + "speedtest_url" + ], + "type": "tag" + } + ], + "hide": false, + "measurement": "upload", + "orderByTime": "ASC", + "policy": "default", + "refId": "C", + "resultFormat": "table", + "select": [ + [ + { + "params": [ + "bandwidth" + ], + "type": "field" + }, + { + "params": [ + "Up Mbps" + ], + "type": "alias" + } + ] + ], + "tags": [ + { + "key": "namespace", + "operator": "=~", + "value": "/^$namespace$/" + } + ] + }, + { + "groupBy": [ + { + "params": [ + "speedtest_url" + ], + "type": "tag" + } + ], + "hide": false, + "measurement": "ping", + "orderByTime": "ASC", + "policy": "default", + "queryType": "randomWalk", + "refId": "A", + "resultFormat": "table", + "select": [ + [ + { + "params": [ + "latency" + ], + "type": "field" + }, + { + "params": [ + "Latency ms" + ], + "type": "alias" + } + ], + [ + { + "params": [ + "jitter" + ], + "type": "field" + }, + { + "params": [ + "Jitter ms" + ], + "type": "alias" + } + ] + ], + "tags": [ + { + "key": "namespace", + "operator": "=~", + "value": "/^$namespace$/" + } + ] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "", + "transformations": [ + { + "id": "merge", + "options": {} + }, + { + "id": "reduce", + "options": { + "includeTimeField": true, + "mode": "reduceFields", + "reducers": [ + "firstNotNull" + ] + } + }, + { + "id": "organize", + "options": { + "excludeByName": { + "Time": false + }, + "indexByName": { + "Down Mbps": 2, + "Jitter ms": 5, + "Latency ms": 4, + "Time": 0, + "Up Mbps": 3, + "speedtest_url": 1 + }, + "renameByName": { + "Down Mbps": "", + "speedtest_url": "SPEEDTEST.net URL" + } + } + } + ], + "type": "table" + }, + { + "datasource": "${DS_INFLUXDB-SPEEDTESTS}", + "description": "", + "fieldConfig": { + "defaults": { + "custom": { + "align": "center", + "filterable": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Time" + }, + "properties": [ + { + "id": "custom.width", + "value": 175 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "SPEEDTEST.net URL" + }, + "properties": [ + { + "id": "custom.width", + "value": 525 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Latency ms" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "dark-green", + "mode": "fixed" + } + }, + { + "id": "custom.displayMode", + "value": "color-background" + } + ] + } + ] + }, + "gridPos": { + "h": 2, + "w": 24, + "x": 0, + "y": 17 + }, + "id": 134, + "options": { + "frameIndex": 0, + "showHeader": false, + "sortBy": [] + }, + "pluginVersion": "7.3.6", + "targets": [ + { + "groupBy": [], + "hide": false, + "measurement": "ping", + "orderByTime": "ASC", + "policy": "default", + "queryType": "randomWalk", + "refId": "A", + "resultFormat": "table", + "select": [ + [ + { + "params": [ + "latency" + ], + "type": "field" + }, + { + "params": [], + "type": "min" + }, + { + "params": [ + "Latency ms" + ], + "type": "alias" + } + ], + [ + { + "params": [ + "jitter" + ], + "type": "field" + }, + { + "params": [ + "Jitter ms" + ], + "type": "alias" + } + ] + ], + "tags": [ + { + "key": "namespace", + "operator": "=~", + "value": "/^$namespace$/" + } + ] + }, + { + "groupBy": [ + { + "params": [ + "speedtest_url" + ], + "type": "tag" + } + ], + "hide": false, + "measurement": "download", + "orderByTime": "ASC", + "policy": "default", + "query": "SELECT max(\"bandwidth\") AS \"Down Mbps\" FROM \"download\" WHERE (\"namespace\" =~ /^$namespace$/) AND $timeFilter", + "rawQuery": false, + "refId": "B", + "resultFormat": "table", + "select": [ + [ + { + "params": [ + "bandwidth" + ], + "type": "field" + }, + { + "params": [ + "Down Mbps" + ], + "type": "alias" + } + ] + ], + "tags": [ + { + "key": "namespace", + "operator": "=~", + "value": "/^$namespace$/" + } + ] + }, + { + "groupBy": [ + { + "params": [ + "speedtest_url" + ], + "type": "tag" + } + ], + "hide": false, + "measurement": "upload", + "orderByTime": "ASC", + "policy": "default", + "refId": "C", + "resultFormat": "table", + "select": [ + [ + { + "params": [ + "bandwidth" + ], + "type": "field" + }, + { + "params": [ + "Up Mbps" + ], + "type": "alias" + } + ] + ], + "tags": [ + { + "key": "namespace", + "operator": "=~", + "value": "/^$namespace$/" + } + ] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "", + "transformations": [ + { + "id": "merge", + "options": {} + }, + { + "id": "reduce", + "options": { + "includeTimeField": true, + "mode": "reduceFields", + "reducers": [ + "firstNotNull" + ] + } + }, + { + "id": "organize", + "options": { + "excludeByName": { + "Time": false + }, + "indexByName": { + "Down Mbps": 2, + "Jitter ms": 5, + "Latency ms": 4, + "Time": 0, + "Up Mbps": 3, + "speedtest_url": 1 + }, + "renameByName": { + "Down Mbps": "", + "speedtest_url": "SPEEDTEST.net URL" + } + } + } + ], + "type": "table" + }, + { + "datasource": "${DS_INFLUXDB-SPEEDTESTS}", + "description": "", + "fieldConfig": { + "defaults": { + "custom": { + "align": "center", + "filterable": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Time" + }, + "properties": [ + { + "id": "custom.width", + "value": 175 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "SPEEDTEST.net URL" + }, + "properties": [ + { + "id": "custom.width", + "value": 525 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Down Mbps" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "semi-dark-yellow", + "mode": "fixed" + } + }, + { + "id": "custom.displayMode", + "value": "color-background" + } + ] + } + ] + }, + "gridPos": { + "h": 2, + "w": 24, + "x": 0, + "y": 19 + }, + "id": 131, + "options": { + "frameIndex": 0, + "showHeader": false, + "sortBy": [] + }, + "pluginVersion": "7.3.6", + "targets": [ + { + "groupBy": [], + "hide": false, + "measurement": "download", + "orderByTime": "ASC", + "policy": "default", + "query": "SELECT max(\"bandwidth\") AS \"Down Mbps\" FROM \"download\" WHERE (\"namespace\" =~ /^$namespace$/) AND $timeFilter", + "rawQuery": false, + "refId": "B", + "resultFormat": "table", + "select": [ + [ + { + "params": [ + "bandwidth" + ], + "type": "field" + }, + { + "params": [], + "type": "min" + }, + { + "params": [ + "Down Mbps" + ], + "type": "alias" + } + ] + ], + "tags": [ + { + "key": "namespace", + "operator": "=~", + "value": "/^$namespace$/" + } + ] + }, + { + "groupBy": [ + { + "params": [ + "speedtest_url" + ], + "type": "tag" + } + ], + "hide": false, + "measurement": "upload", + "orderByTime": "ASC", + "policy": "default", + "refId": "C", + "resultFormat": "table", + "select": [ + [ + { + "params": [ + "bandwidth" + ], + "type": "field" + }, + { + "params": [ + "Up Mbps" + ], + "type": "alias" + } + ] + ], + "tags": [ + { + "key": "namespace", + "operator": "=~", + "value": "/^$namespace$/" + } + ] + }, + { + "groupBy": [ + { + "params": [ + "speedtest_url" + ], + "type": "tag" + } + ], + "hide": false, + "measurement": "ping", + "orderByTime": "ASC", + "policy": "default", + "queryType": "randomWalk", + "refId": "A", + "resultFormat": "table", + "select": [ + [ + { + "params": [ + "latency" + ], + "type": "field" + }, + { + "params": [ + "Latency ms" + ], + "type": "alias" + } + ], + [ + { + "params": [ + "jitter" + ], + "type": "field" + }, + { + "params": [ + "Jitter ms" + ], + "type": "alias" + } + ] + ], + "tags": [ + { + "key": "namespace", + "operator": "=~", + "value": "/^$namespace$/" + } + ] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "", + "transformations": [ + { + "id": "merge", + "options": {} + }, + { + "id": "reduce", + "options": { + "includeTimeField": true, + "mode": "reduceFields", + "reducers": [ + "firstNotNull" + ] + } + }, + { + "id": "organize", + "options": { + "excludeByName": { + "Time": false + }, + "indexByName": { + "Down Mbps": 2, + "Jitter ms": 5, + "Latency ms": 4, + "Time": 0, + "Up Mbps": 3, + "speedtest_url": 1 + }, + "renameByName": { + "Down Mbps": "", + "speedtest_url": "SPEEDTEST.net URL" + } + } + } + ], + "type": "table" + }, + { + "datasource": "${DS_INFLUXDB-SPEEDTESTS}", + "description": "", + "fieldConfig": { + "defaults": { + "custom": { + "align": "center", + "filterable": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Time" + }, + "properties": [ + { + "id": "custom.width", + "value": 175 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "SPEEDTEST.net URL" + }, + "properties": [ + { + "id": "custom.width", + "value": 525 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Latency ms" + }, + "properties": [ + { + "id": "color", + "value": { + "fixedColor": "semi-dark-yellow", + "mode": "fixed" + } + }, + { + "id": "custom.displayMode", + "value": "color-background" + } + ] + } + ] + }, + "gridPos": { + "h": 2, + "w": 24, + "x": 0, + "y": 21 + }, + "id": 135, + "options": { + "frameIndex": 0, + "showHeader": false, + "sortBy": [] + }, + "pluginVersion": "7.3.6", + "targets": [ + { + "groupBy": [], + "hide": false, + "measurement": "ping", + "orderByTime": "ASC", + "policy": "default", + "queryType": "randomWalk", + "refId": "A", + "resultFormat": "table", + "select": [ + [ + { + "params": [ + "latency" + ], + "type": "field" + }, + { + "params": [], + "type": "max" + }, + { + "params": [ + "Latency ms" + ], + "type": "alias" + } + ], + [ + { + "params": [ + "jitter" + ], + "type": "field" + }, + { + "params": [ + "Jitter ms" + ], + "type": "alias" + } + ] + ], + "tags": [ + { + "key": "namespace", + "operator": "=~", + "value": "/^$namespace$/" + } + ] + }, + { + "groupBy": [ + { + "params": [ + "speedtest_url" + ], + "type": "tag" + } + ], + "hide": false, + "measurement": "download", + "orderByTime": "ASC", + "policy": "default", + "query": "SELECT max(\"bandwidth\") AS \"Down Mbps\" FROM \"download\" WHERE (\"namespace\" =~ /^$namespace$/) AND $timeFilter", + "rawQuery": false, + "refId": "B", + "resultFormat": "table", + "select": [ + [ + { + "params": [ + "bandwidth" + ], + "type": "field" + }, + { + "params": [ + "Down Mbps" + ], + "type": "alias" + } + ] + ], + "tags": [ + { + "key": "namespace", + "operator": "=~", + "value": "/^$namespace$/" + } + ] + }, + { + "groupBy": [ + { + "params": [ + "speedtest_url" + ], + "type": "tag" + } + ], + "hide": false, + "measurement": "upload", + "orderByTime": "ASC", + "policy": "default", + "refId": "C", + "resultFormat": "table", + "select": [ + [ + { + "params": [ + "bandwidth" + ], + "type": "field" + }, + { + "params": [ + "Up Mbps" + ], + "type": "alias" + } + ] + ], + "tags": [ + { + "key": "namespace", + "operator": "=~", + "value": "/^$namespace$/" + } + ] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "", + "transformations": [ + { + "id": "merge", + "options": {} + }, + { + "id": "reduce", + "options": { + "includeTimeField": true, + "mode": "reduceFields", + "reducers": [ + "firstNotNull" + ] + } + }, + { + "id": "organize", + "options": { + "excludeByName": { + "Time": false + }, + "indexByName": { + "Down Mbps": 2, + "Jitter ms": 5, + "Latency ms": 4, + "Time": 0, + "Up Mbps": 3, + "speedtest_url": 1 + }, + "renameByName": { + "Down Mbps": "", + "speedtest_url": "SPEEDTEST.net URL" + } + } + } + ], + "type": "table" + }, + { + "collapsed": false, + "datasource": "${DS_INFLUXDB-SPEEDTESTS}", + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 23 + }, + "id": 108, + "panels": [], + "title": "Averages by Test Server", + "type": "row" + }, + { + "datasource": "${DS_INFLUXDB-SPEEDTESTS}", + "description": "Shows the avg speeds received by test site", + "fieldConfig": { + "defaults": { + "custom": { + "align": "center", + "displayMode": "color-background", + "filterable": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "Mbits" + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Ping" + }, + "properties": [ + { + "id": "unit", + "value": "ms" + }, + { + "id": "thresholds", + "value": { + "mode": "percentage", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "#EAB839", + "value": 25 + }, + { + "color": "red", + "value": 50 + } + ] + } + }, + { + "id": "custom.displayMode", + "value": "gradient-gauge" + }, + { + "id": "max", + "value": 100 + }, + { + "id": "custom.width" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Test Count" + }, + "properties": [ + { + "id": "unit", + "value": "none" + }, + { + "id": "custom.displayMode", + "value": "gradient-gauge" + }, + { + "id": "max", + "value": 25 + }, + { + "id": "custom.width", + "value": 150 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Location" + }, + "properties": [ + { + "id": "custom.displayMode", + "value": "color-text" + }, + { + "id": "custom.width", + "value": 180 + }, + { + "id": "custom.align", + "value": "left" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Download Avg" + }, + "properties": [ + { + "id": "custom.displayMode", + "value": "gradient-gauge" + }, + { + "id": "thresholds", + "value": { + "mode": "absolute", + "steps": [ + { + "color": "red", + "value": null + }, + { + "color": "yellow", + "value": 50 + }, + { + "color": "green", + "value": 100 + } + ] + } + }, + { + "id": "max" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Upload Avg" + }, + "properties": [ + { + "id": "custom.displayMode", + "value": "gradient-gauge" + }, + { + "id": "thresholds", + "value": { + "mode": "absolute", + "steps": [ + { + "color": "red", + "value": null + }, + { + "color": "yellow", + "value": 10 + }, + { + "color": "green", + "value": 50 + } + ] + } + }, + { + "id": "max" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Server" + }, + "properties": [ + { + "id": "custom.width", + "value": 300 + }, + { + "id": "custom.align", + "value": "left" + } + ] + } + ] + }, + "gridPos": { + "h": 12, + "w": 24, + "x": 0, + "y": 24 + }, + "id": 114, + "options": { + "showHeader": true, + "sortBy": [ + { + "desc": false, + "displayName": "Ping" + } + ] + }, + "pluginVersion": "7.3.6", + "targets": [ + { + "groupBy": [ + { + "params": [ + "server_name" + ], + "type": "tag" + }, + { + "params": [ + "server_location" + ], + "type": "tag" + }, + { + "params": [ + "server_id" + ], + "type": "tag" + } + ], + "measurement": "download", + "orderByTime": "ASC", + "policy": "default", + "query": "SELECT mean(\"bandwidth\") AS \"Download Avg\" FROM \"download\" WHERE $timeFilter GROUP BY \"server_name\", \"server_location\"", + "rawQuery": false, + "refId": "A", + "resultFormat": "table", + "select": [ + [ + { + "params": [ + "bandwidth" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + }, + { + "params": [ + "Download Avg" + ], + "type": "alias" + } + ], + [ + { + "params": [ + "bandwidth" + ], + "type": "field" + }, + { + "params": [], + "type": "count" + }, + { + "params": [ + "Test Count" + ], + "type": "alias" + } + ] + ], + "tags": [ + { + "key": "namespace", + "operator": "=~", + "value": "/^$namespace$/" + } + ] + }, + { + "groupBy": [ + { + "params": [ + "server_id" + ], + "type": "tag" + } + ], + "measurement": "upload", + "orderByTime": "ASC", + "policy": "default", + "query": "SELECT mean(\"bandwidth\") AS \"Upload Avg\" FROM \"upload\" WHERE $timeFilter GROUP BY \"server_id\"", + "rawQuery": false, + "refId": "B", + "resultFormat": "table", + "select": [ + [ + { + "params": [ + "bandwidth" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + }, + { + "params": [ + "Upload Avg" + ], + "type": "alias" + } + ] + ], + "tags": [ + { + "key": "namespace", + "operator": "=~", + "value": "/^$namespace$/" + } + ] + }, + { + "groupBy": [ + { + "params": [ + "server_id" + ], + "type": "tag" + } + ], + "measurement": "ping", + "orderByTime": "ASC", + "policy": "default", + "query": "SELECT mean(\"bandwidth\") AS \"Upload Avg\" FROM \"upload\" WHERE $timeFilter GROUP BY \"server_id\"", + "rawQuery": false, + "refId": "C", + "resultFormat": "table", + "select": [ + [ + { + "params": [ + "latency" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + }, + { + "params": [ + "Ping" + ], + "type": "alias" + } + ] + ], + "tags": [ + { + "key": "namespace", + "operator": "=~", + "value": "/^$namespace$/" + } + ] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "", + "transformations": [ + { + "id": "seriesToColumns", + "options": { + "byField": "server_id" + } + }, + { + "id": "organize", + "options": { + "excludeByName": { + "Time": true, + "Time 1": true, + "Time 2": true, + "Time 3": true, + "server_id": true + }, + "indexByName": { + "Download Avg": 3, + "Ping": 2, + "Test Count": 7, + "Time 1": 6, + "Time 2": 8, + "Time 3": 9, + "Upload Avg": 4, + "server_id": 5, + "server_location": 1, + "server_name": 0 + }, + "renameByName": { + "Time": "", + "server_location": "Location", + "server_name": "Server" + } + } + } + ], + "type": "table" + }, + { + "collapsed": true, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 36 + }, + "id": 129, + "panels": [ + { + "datasource": "${DS_INFLUXDB-SPEEDTESTS}", + "fieldConfig": { + "defaults": { + "custom": { + "align": "center", + "filterable": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Time" + }, + "properties": [ + { + "id": "custom.width", + "value": 175 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "SPEEDTEST.net URL" + }, + "properties": [ + { + "id": "custom.width", + "value": 525 + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 37 + }, + "id": 130, + "options": { + "frameIndex": 0, + "showHeader": true, + "sortBy": [ + { + "desc": true, + "displayName": "Down Mbps" + } + ] + }, + "pluginVersion": "7.3.6", + "targets": [ + { + "groupBy": [ + { + "params": [ + "speedtest_url" + ], + "type": "tag" + } + ], + "hide": false, + "measurement": "download", + "orderByTime": "ASC", + "policy": "default", + "query": "SELECT max(\"bandwidth\") AS \"Down Mbps\" FROM \"download\" WHERE (\"namespace\" =~ /^$namespace$/) AND $timeFilter", + "rawQuery": false, + "refId": "B", + "resultFormat": "table", + "select": [ + [ + { + "params": [ + "bandwidth" + ], + "type": "field" + }, + { + "params": [ + "Down Mbps" + ], + "type": "alias" + } + ] + ], + "tags": [ + { + "key": "namespace", + "operator": "=~", + "value": "/^$namespace$/" + } + ] + }, + { + "groupBy": [ + { + "params": [ + "speedtest_url" + ], + "type": "tag" + } + ], + "hide": false, + "measurement": "upload", + "orderByTime": "ASC", + "policy": "default", + "refId": "C", + "resultFormat": "table", + "select": [ + [ + { + "params": [ + "bandwidth" + ], + "type": "field" + }, + { + "params": [ + "Up Mbps" + ], + "type": "alias" + } + ] + ], + "tags": [ + { + "key": "namespace", + "operator": "=~", + "value": "/^$namespace$/" + } + ] + }, + { + "groupBy": [ + { + "params": [ + "speedtest_url" + ], + "type": "tag" + } + ], + "hide": false, + "measurement": "ping", + "orderByTime": "ASC", + "policy": "default", + "queryType": "randomWalk", + "refId": "A", + "resultFormat": "table", + "select": [ + [ + { + "params": [ + "latency" + ], + "type": "field" + }, + { + "params": [ + "Latency ms" + ], + "type": "alias" + } + ], + [ + { + "params": [ + "jitter" + ], + "type": "field" + }, + { + "params": [ + "Jitter ms" + ], + "type": "alias" + } + ] + ], + "tags": [ + { + "key": "namespace", + "operator": "=~", + "value": "/^$namespace$/" + } + ] + } + ], + "timeFrom": null, + "timeShift": null, + "title": "All Raw", + "transformations": [ + { + "id": "merge", + "options": {} + }, + { + "id": "organize", + "options": { + "excludeByName": { + "Time": false + }, + "indexByName": { + "Down Mbps": 2, + "Jitter ms": 5, + "Latency ms": 4, + "Time": 0, + "Up Mbps": 3, + "speedtest_url": 1 + }, + "renameByName": { + "Down Mbps": "", + "speedtest_url": "SPEEDTEST.net URL" + } + } + } + ], + "type": "table" + } + ], + "title": "Raw Results & Links", + "type": "row" + } + ], + "refresh": false, + "schemaVersion": 26, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "allValue": null, + "current": {}, + "datasource": "${DS_INFLUXDB-SPEEDTESTS}", + "definition": "", + "error": null, + "hide": 1, + "includeAll": false, + "label": "namespace", + "multi": false, + "name": "namespace", + "options": [], + "query": "SHOW TAG VALUES FROM ping WITH Key = \"namespace\"", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-2d", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ] + }, + "timezone": "", + "title": "SpeedTests", + "uid": "kLXTiedGz", + "version": 38 +} diff --git a/README.md b/README.md index b31d47c..5ab6832 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,9 @@ This is a Python script that will continuously run the official Speedtest CLI ap This script will allow you to measure your internet connections speed and consistency over time. It uses env variables as configuration. It's as easy to use as telling your Docker server a 1 line command and you'll be set. Using Grafana you can start exploring this data easily. -I built a grafana dashboard for this data that can be found at https://grafana.com/grafana/dashboards/13053 +I built a Grafana dashboard which has been exported into this repo as `GrafanaDash-SpeedTests.json` to import into Grafana for your convenience. -![Grafana Dashboard](https://grafana.com/api/dashboards/13053/images/8976/image) +![GrafanaDashboard](https://user-images.githubusercontent.com/945191/105287048-46f52a80-5b6c-11eb-9e57-038d63b67efb.png) There are some added features to allow some additional details that Ookla provides as tags on your data. Some examples are your current ISP, the interface being used, the server who hosted the test. Overtime, you could identify if some serers are performing better than others. @@ -15,19 +15,23 @@ There are some added features to allow some additional details that Ookla provid The InfluxDB connection settings are controlled by environment variables. The variables available are: -- INFLUX_DB_ADDRESS = 192.168.1.xxx -- INFLUX_DB_PORT = 8086 -- INFLUX_DB_USER = user -- INFLUX_DB_PASSWORD = pass -- INFLUX_DB_DATABASE = speedtest -- INFLUX_DB_TAGS = *comma seperated list of tags. See below for options* -- SPEEDTEST_INTERVAL = 60 -- SPEEDTEST_FAIL_INTERVAL = 5 +- NAMESPACE = default - None +- INFLUX_DB_ADDRESS = default - influxdb +- INFLUX_DB_PORT = default - 8086 +- INFLUX_DB_USER = default - {blank} +- INFLUX_DB_PASSWORD = default - {blank} +- INFLUX_DB_DATABASE = default - speedtests +- INFLUX_DB_TAGS = default - None * See below for options, '*' widcard for all * +- SPEEDTEST_INTERVAL = default - 5 (minutes) +- SPEEDTEST_SERVER_ID = default - {blank} * id from https://c.speedtest.net/speedtest-servers-static.php * +- PING_INTERVAL = default - 5 (seconds) +- PING_TARGETS = default - 1.1.1.1, 8.8.8.8 (csv of hosts to ping) ### Variable Notes - Intervals are in minutes. *Script will convert it to seconds.* - If any variables are not needed, don't declare them. Functions will operate with or without most variables. - Tags should be input without quotes. *INFLUX_DB_TAGS = isp, interface, external_ip, server_name, speedtest_url* +- NAMESPACE is used to collect data from multiple instances of the container into one database and select which you wish to view in Grafana. i.e. I have one monitoring my Starlink, the other my TELUS connection. ### Tag Options The Ookla speedtest app provides a nice set of data beyond the upload and download speed. The list is below. @@ -59,40 +63,21 @@ Be aware that this script will automatically accept the license and GDPR stateme 1. Build the container. - `docker build -t breadlysm/speedtest-to-influxdb ./` + `docker build -t qlustor/speedtest_ookla-to-influxdb ./` 2. Run the container. ``` - docker run -d --name speedtest-influx \ - -e 'INFLUX_DB_ADDRESS'='_influxdb_host_' \ + docker run -d -t --name speedflux \ + -e 'NAMESPACE'='None' \ + -e 'INFLUX_DB_ADDRESS'='influxdb' \ -e 'INFLUX_DB_PORT'='8086' \ -e 'INFLUX_DB_USER'='_influx_user_' \ -e 'INFLUX_DB_PASSWORD'='_influx_pass_' \ - -e 'INFLUX_DB_DATABASE'='speedtest' \ - -e 'SPEEDTEST_INTERVAL'='1800' \ - -e 'SPEEDTEST_FAIL_INTERVAL'='60' \ - breadlysm/speedtest-to-influxdb + -e 'INFLUX_DB_DATABASE'='speedtests' \ + -e 'SPEEDTEST_INTERVAL'='5' \ + -e 'SPEEDTEST_FAIL_INTERVAL'='5' \ + -e 'SPEEDTEST_SERVER_ID'='12746' \ + qlustor/speedtest_ookla-to-influxdb ``` -### No Container -1. Clone the repo - - `git clone https://github.com/breadlysm/speedtest-to-influxdb.git` - -2. Configure the .env file in the repo or set the environment variables on your device. - -3. [Install the Speedtest CLI application by Ookla.](https://www.speedtest.net/apps/cli) - - NOTE: The `speedtest-cli` package in distro repositories is an unofficial client. It will need to be uninstalled before installing the Ookla Speedtest CLI application with the directions on their website. - -4. Install the InfluxDB client for library from Python. - - `pip install influxdb` - -5. Run the script. - - `python3 ./main.py` - - - -This script looks to have been originally written by https://github.com/aidengilmartin/speedtest-to-influxdb/blob/master/main.py and I forked it from https://github.com/martinfrancois/speedtest-to-influxdb. They did the hard work, I've continued to modify it though to fit my needs. +This script looks to have been originally written by https://github.com/aidengilmartin/speedtest-to-influxdb/blob/master/main.py and I forked it from https://github.com/breadlysm/speedtest-to-influxdb. They did the hard work, I've continued to modify it though to fit my needs. diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100644 index 0000000..9198112 --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +printenv >> /etc/environment +ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone + +# Install speedtest-cli +if [ ! -e /usr/bin/speedtest ] +then + apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 379CE192D401AB61 + echo "deb https://ookla.bintray.com/debian buster main" | tee /etc/apt/sources.list.d/speedtest.list + apt-get update && apt-get -q -y install speedtest + apt-get -q -y autoremove && apt-get -q -y clean + rm -rf /var/lib/apt/lists/* +fi + +exec /usr/local/bin/python3 $@ diff --git a/main.py b/main.py index 9c3b4b2..cb8a782 100755 --- a/main.py +++ b/main.py @@ -1,22 +1,31 @@ +import os import time import json +import datetime import subprocess -import os +from pythonping import ping from influxdb import InfluxDBClient +from multiprocessing import Process # InfluxDB Settings -DB_ADDRESS = os.environ.get('INFLUX_DB_ADDRESS') -DB_PORT = int(os.environ.get('INFLUX_DB_PORT')) -DB_USER = os.environ.get('INFLUX_DB_USER') -DB_PASSWORD = os.environ.get('INFLUX_DB_PASSWORD') -DB_DATABASE = os.environ.get('INFLUX_DB_DATABASE') -DB_TAGS = os.environ.get('INFLUX_DB_TAGS') +NAMESPACE = os.getenv('NAMESPACE', 'None') +DB_ADDRESS = os.getenv('INFLUX_DB_ADDRESS', 'influxdb') +DB_PORT = int(os.getenv('INFLUX_DB_PORT', '8086')) +DB_USER = os.getenv('INFLUX_DB_USER', '') +DB_PASSWORD = os.getenv('INFLUX_DB_PASSWORD', '') +DB_DATABASE = os.getenv('INFLUX_DB_DATABASE', 'speedtests') +DB_TAGS = os.getenv('INFLUX_DB_TAGS', None) +PING_TARGETS = os.getenv('PING_TARGETS', '1.1.1.1, 8.8.8.8') # Speedtest Settings # Time between tests (in minutes, converts to seconds). -TEST_INTERVAL = int(os.environ.get('SPEEDTEST_INTERVAL')) * 60 +TEST_INTERVAL = int(os.getenv('SPEEDTEST_INTERVAL', '5')) * 60 # Time before retrying a failed Speedtest (in minutes, converts to seconds). -TEST_FAIL_INTERVAL = int(os.environ.get('SPEEDTEST_FAIL_INTERVAL')) * 60 +TEST_FAIL_INTERVAL = int(os.getenv('SPEEDTEST_FAIL_INTERVAL', '5')) * 60 +# Specific server ID +SERVER_ID = os.getenv('SPEEDTEST_SERVER_ID', '') +# Time between ping tests (in seconds). +PING_INTERVAL = int(os.getenv('PING_INTERVAL', '5')) influxdb_client = InfluxDBClient( DB_ADDRESS, DB_PORT, DB_USER, DB_PASSWORD, None) @@ -42,10 +51,11 @@ def pkt_loss(data): def tag_selection(data): tags = DB_TAGS - if tags is None: - return None + options = {} + # tag_switch takes in _data and attaches CLIoutput to more readable ids tag_switch = { + 'namespace': NAMESPACE, 'isp': data['isp'], 'interface': data['interface']['name'], 'internal_ip': data['interface']['internalIp'], @@ -62,18 +72,25 @@ def tag_selection(data): 'speedtest_id': data['result']['id'], 'speedtest_url': data['result']['url'] } - - options = {} + + if tags is None: + tags = 'namespace' + elif '*' in tags: + return tag_switch + else: + tags = 'namespace, ' + tags + tags = tags.split(',') for tag in tags: # split the tag string, strip and add selected tags to {options} with corresponding tag_switch data tag = tag.strip() options[tag] = tag_switch[tag] + return options -def format_for_influx(cliout): - data = json.loads(cliout) +def format_for_influx(data): + # There is additional data in the speedtest-cli output but it is likely not necessary to store. influx_data = [ { @@ -110,37 +127,107 @@ def format_for_influx(cliout): 'fields': { 'packetLoss': pkt_loss(data) } + }, + { + 'measurement': 'speeds', + 'time': data['timestamp'], + 'fields': { + 'jitter': data['ping']['jitter'], + 'latency': data['ping']['latency'], + 'packetLoss': pkt_loss(data), + # Byte to Megabit + 'bandwidth_down': data['download']['bandwidth'] / 125000, + 'bytes_down': data['download']['bytes'], + 'elapsed_down': data['download']['elapsed'], + # Byte to Megabit + 'bandwidth_up': data['upload']['bandwidth'] / 125000, + 'bytes_up': data['upload']['bytes'], + 'elapsed_up': data['upload']['elapsed'] + } } ] tags = tag_selection(data) - if tags is None: - return influx_data - else: + if tags is not None: for measurement in influx_data: measurement['tags'] = tags - return influx_data + return influx_data + + +def speedtest(): + if not SERVER_ID: + speedtest = subprocess.run( + ["speedtest", "--accept-license", "--accept-gdpr", "-f", "json"], capture_output=True) + print("Automatic server choice") + else: + speedtest = subprocess.run( + ["speedtest", "--accept-license", "--accept-gdpr", "-f", "json", "--server-id=" + SERVER_ID], capture_output=True) + print("Manual server choice : ID = " + SERVER_ID) + + if speedtest.returncode == 0: # Speedtest was successful. + print("Speedtest Successful :") + data_json = json.loads(speedtest.stdout) + print("time: " + str(data_json['timestamp']) + " - ping: " + str(data_json['ping']['latency']) + " ms - download: " + str(data_json['download']['bandwidth']/125000) + " Mb/s - upload: " + str(data_json['upload']['bandwidth'] / 125000) + " Mb/s - isp: " + data_json['isp'] + " - ext. IP: " + data_json['interface']['externalIp'] + " - server id: " + str(data_json['server']['id']) + " (" + data_json['server']['name'] + " @ " + data_json['server']['location'] + ")") + data = format_for_influx(data_json) + if influxdb_client.write_points(data) == True: + print("Data written to DB successfully") + else: # Speedtest failed. + print("Speedtest Failed :") + print(speedtest.stderr) + print(speedtest.stdout) +# time.sleep(TEST_FAIL_INTERVAL) + + +def pingtest(): + timestamp = datetime.datetime.utcnow() + for target in PING_TARGETS.split(','): + target = target.strip() + pingtest = ping(target, verbose=False, timeout=1, count=1, size=128) + data = [ + { + 'measurement': 'pings', + 'time': timestamp, + 'tags': { + 'namespace': NAMESPACE, + 'target' : target + }, + 'fields': { + 'success' : int(pingtest._responses[0].error_message is None), + 'rtt': float(0 if pingtest._responses[0].error_message is not None else pingtest.rtt_avg_ms) + } + } + ] + if influxdb_client.write_points(data) == True: + print("Ping data written to DB successfully") + else: # Speedtest failed. + print("Ping Failed.") def main(): + pPing = Process(target=pingtest) + pSpeed = Process(target=speedtest) + init_db() # Setup the database if it does not already exist. + loopcount = 0 while (1): # Run a Speedtest and send the results to influxDB indefinitely. - speedtest = subprocess.run( - ["speedtest", "--accept-license", "--accept-gdpr", "-f", "json"], capture_output=True) + if loopcount == 0 or loopcount % PING_INTERVAL == 0: + if pPing.is_alive(): + pPing.terminate() + pPing = Process(target=pingtest) + pPing.start() - if speedtest.returncode == 0: # Speedtest was successful. - data = format_for_influx(speedtest.stdout) - print("Speedtest Successful:") - if influxdb_client.write_points(data) == True: - print("Data written to DB successfully") - time.sleep(TEST_INTERVAL) - else: # Speedtest failed. - print("Speedtest Failed:") - print(speedtest.stderr) - print(speedtest.stdout) - time.sleep(TEST_FAIL_INTERVAL) + if loopcount == 0 or loopcount % TEST_INTERVAL == 0: + if pSpeed.is_alive(): + pSpeed.terminate() + pSpeed = Process(target=speedtest) + pSpeed.start() + if loopcount % ( PING_INTERVAL * TEST_INTERVAL ) == 0: + loopcount = 0 + + time.sleep(1) + loopcount += 1 if __name__ == '__main__': - print('Speedtest CLI Data Logger to InfluxDB') + print('Speedtest CLI data logger to InfluxDB started...') main() diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 1d4ac6e..0000000 --- a/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -influxdb \ No newline at end of file