diff --git a/grafana-dashboards/speedtest-exporter-dashboard.json b/grafana-dashboards/speedtest-exporter-dashboard.json new file mode 100644 index 0000000..c965b08 --- /dev/null +++ b/grafana-dashboards/speedtest-exporter-dashboard.json @@ -0,0 +1,373 @@ +{ + "__inputs": [ + { + "name": "DS_PROMETHEUS", + "label": "Prometheus", + "description": "", + "type": "datasource", + "pluginId": "prometheus", + "pluginName": "Prometheus" + } + ], + "__requires": [ + { + "type": "grafana", + "id": "grafana", + "name": "Grafana", + "version": "7.2.1" + }, + { + "type": "panel", + "id": "graph", + "name": "Graph", + "version": "" + }, + { + "type": "datasource", + "id": "prometheus", + "name": "Prometheus", + "version": "1.0.0" + } + ], + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": null, + "links": [], + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PROMETHEUS}", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 10, + "gridPos": { + "h": 9, + "w": 8, + "x": 0, + "y": 0 + }, + "hiddenSeries": false, + "id": 4, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "max": true, + "min": true, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.2.1", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "speedtest_ping_latency_milliseconds", + "interval": "", + "legendFormat": "Ping (ms)", + "refId": "A" + }, + { + "expr": "speedtest_jitter_latency_milliseconds", + "interval": "", + "legendFormat": "Jitter (ms)", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Ping and Jitter (ms)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:291", + "format": "ms", + "label": "Time", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:292", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PROMETHEUS}", + "description": "", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 10, + "gridPos": { + "h": 9, + "w": 8, + "x": 8, + "y": 0 + }, + "hiddenSeries": false, + "id": 2, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.2.1", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "speedtest_download_bits_per_second*10^-6", + "interval": "", + "legendFormat": "Download Speed (Mbits/s)", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Download Speed (Mbits/s)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:291", + "format": "Mbits", + "label": "Download Speed", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:292", + "decimals": null, + "format": "dateTimeAsLocal", + "label": "", + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PROMETHEUS}", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 10, + "gridPos": { + "h": 9, + "w": 8, + "x": 16, + "y": 0 + }, + "hiddenSeries": false, + "id": 3, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.2.1", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "speedtest_upload_bits_per_second*10^-6", + "interval": "", + "legendFormat": "Upload Speed (Mbits/s)", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Upload Speed (Mbits/s)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:291", + "decimals": null, + "format": "Mbits", + "label": "Upload Speed", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:292", + "decimals": null, + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "refresh": false, + "schemaVersion": 26, + "style": "dark", + "tags": [], + "templating": { + "list": [] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "Speedtest Dashboard", + "uid": "-fs18ztMz", + "version": 4 +} diff --git a/modules/speedtest_exporter.jsonnet b/modules/speedtest_exporter.jsonnet new file mode 100644 index 0000000..77056ff --- /dev/null +++ b/modules/speedtest_exporter.jsonnet @@ -0,0 +1,51 @@ +local utils = import '../utils.libsonnet'; +local k = import 'ksonnet/ksonnet.beta.4/k.libsonnet'; + +{ + _config+:: { + namespace: 'monitoring', + replicas: 1, + + imageRepos+:: { + speedtestExporter: 'ghcr.io/miguelndecarvalho/speedtest-exporter', + }, + + // Add custom dashboards + grafanaDashboards+:: { + 'speedtest-exporter-dashboard.json': (import '../grafana-dashboards/speedtest-exporter-dashboard.json'), + }, + }, + + speedtestExporter+:: { + deployment: + local deployment = k.apps.v1.deployment; + local container = k.apps.v1.deployment.mixin.spec.template.spec.containersType; + local containerPort = container.portsType; + + local podLabels = { 'k8s-app': 'speedtest-exporter' }; + local speedtestExporter = + container.new('speedtest-exporter', + $._config.imageRepos.speedtestExporter) + + container.withPorts(containerPort.newNamed(9798, 'metrics')); + + local c = [speedtestExporter]; + + deployment.new('speedtest-exporter', $._config.replicas, c, podLabels) + + deployment.mixin.metadata.withNamespace($._config.namespace) + + deployment.mixin.metadata.withLabels(podLabels) + + deployment.mixin.spec.selector.withMatchLabels(podLabels) + + deployment.mixin.spec.template.spec.withRestartPolicy('Always'), + + service: + local service = k.core.v1.service; + local servicePort = k.core.v1.service.mixin.spec.portsType; + local speedtestExporterPorts = servicePort.newNamed('metrics', 9798, 'metrics'); + + service.new('speedtest-exporter', $.speedtestExporter.deployment.spec.selector.matchLabels, speedtestExporterPorts) + + service.mixin.metadata.withNamespace($._config.namespace) + + service.mixin.metadata.withLabels({ 'k8s-app': 'speedtest-exporter' }), + + serviceMonitor: + utils.newServiceMonitor('speedtest-exporter', $._config.namespace, { 'k8s-app': 'speedtest-exporter' }, $._config.namespace, 'metrics', 'http', 'metrics', '30m', '2m'), + }, +} diff --git a/utils.libsonnet b/utils.libsonnet index b4f8545..6129d60 100644 --- a/utils.libsonnet +++ b/utils.libsonnet @@ -175,7 +175,7 @@ local k = import 'ksonnet/ksonnet.beta.4/k.libsonnet'; ), // Creates http ServiceMonitor objects - newServiceMonitor(name, namespace, matchLabel, matchNamespace, portName, portScheme, path='metrics'):: ( + newServiceMonitor(name, namespace, matchLabel, matchNamespace, portName, portScheme, path='metrics', interval='30s', timeout='30s'):: ( { apiVersion: 'monitoring.coreos.com/v1', kind: 'ServiceMonitor', @@ -195,7 +195,8 @@ local k = import 'ksonnet/ksonnet.beta.4/k.libsonnet'; { port: portName, scheme: portScheme, - interval: '30s', + interval: interval, + scrapeTimeout: timeout, relabelings: [ { action: 'replace', diff --git a/vars.jsonnet b/vars.jsonnet index 201365b..97d821d 100644 --- a/vars.jsonnet +++ b/vars.jsonnet @@ -40,6 +40,11 @@ enabled: false, file: import 'modules/elasticsearch_exporter.jsonnet', }, + { + name: 'speedtestExporter', + enabled: false, + file: import 'modules/speedtest_exporter.jsonnet', + }, ], k3s: {