From a1ae28120bbc4d812605d0cc1dad1e3d282654d1 Mon Sep 17 00:00:00 2001 From: Tom Wilkie Date: Mon, 12 Oct 2020 18:01:09 +0100 Subject: [PATCH] Add a bare-bones 'monitoring mixin' for dnsmasq. (#10) --- dnsmasq-mixin/Makefile | 21 + dnsmasq-mixin/README.md | 26 ++ dnsmasq-mixin/dnsmasq-overview.json | 670 ++++++++++++++++++++++++++++ dnsmasq-mixin/go.mod | 9 + dnsmasq-mixin/mixin.libsonnet | 5 + 5 files changed, 731 insertions(+) create mode 100644 dnsmasq-mixin/Makefile create mode 100644 dnsmasq-mixin/README.md create mode 100644 dnsmasq-mixin/dnsmasq-overview.json create mode 100644 dnsmasq-mixin/go.mod create mode 100644 dnsmasq-mixin/mixin.libsonnet diff --git a/dnsmasq-mixin/Makefile b/dnsmasq-mixin/Makefile new file mode 100644 index 0000000..7bdad5d --- /dev/null +++ b/dnsmasq-mixin/Makefile @@ -0,0 +1,21 @@ +JSONNET_FMT := jsonnetfmt -n 2 --max-blank-lines 2 --string-style s --comment-style s + +all: fmt lint build clean + +fmt: + find . -name 'vendor' -prune -o -name '*.libsonnet' -print -o -name '*.jsonnet' -print | \ + xargs -n 1 -- $(JSONNET_FMT) -i + +lint: + find . -name 'vendor' -prune -o -name '*.libsonnet' -print -o -name '*.jsonnet' -print | \ + while read f; do \ + $(JSONNET_FMT) "$$f" | diff -u "$$f" -; \ + done + + mixtool lint mixin.libsonnet + +build: + mixtool generate all mixin.libsonnet + +clean: + rm -rf dashboards_out alerts.yaml rules.yaml diff --git a/dnsmasq-mixin/README.md b/dnsmasq-mixin/README.md new file mode 100644 index 0000000..22f28f3 --- /dev/null +++ b/dnsmasq-mixin/README.md @@ -0,0 +1,26 @@ +# dnsmasq mixin + +_This is a work in progress. We aim for it to become a good role model for alerts +and dashboards eventually, but it is not quite there yet._ + +The dnsmasq mixin is a set of configurable, reusable, and extensible alerts and +dashboards based on the metrics exported by the dnsmasq exporter. The mixin creates +recording and alerting rules for Prometheus and suitable dashboard descriptions +for Grafana. + +To use them, you need to have `mixtool` and `jsonnetfmt` installed. If you +have a working Go development environment, it's easiest to run the following: +```bash +$ go get github.com/monitoring-mixins/mixtool/cmd/mixtool +$ go get github.com/google/go-jsonnet/cmd/jsonnetfmt +``` + +You can then build the Prometheus rules files `alerts.yaml` and +`rules.yaml` and a directory `dashboard_out` with the JSON dashboard files +for Grafana: +```bash +$ make build +``` + +For more advanced uses of mixins, see +https://github.com/monitoring-mixins/docs. diff --git a/dnsmasq-mixin/dnsmasq-overview.json b/dnsmasq-mixin/dnsmasq-overview.json new file mode 100644 index 0000000..263896e --- /dev/null +++ b/dnsmasq-mixin/dnsmasq-overview.json @@ -0,0 +1,670 @@ +{ + "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": 34, + "iteration": 1602437170658, + "links": [], + "panels": [ + { + "collapsed": false, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 15, + "panels": [], + "title": "DNS Stats", + "type": "row" + }, + { + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 6, + "x": 0, + "y": 1 + }, + "id": 2, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "mean" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.4", + "targets": [ + { + "expr": "sum(dnsmasq_leases{job=~\"$job\", instance=~\"$instance\"})", + "instant": false, + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Leases", + "type": "stat" + }, + { + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "noValue": "0", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 6, + "x": 6, + "y": 1 + }, + "id": 16, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "mean" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.4", + "targets": [ + { + "expr": "sum(dnsmasq_servers_queries{job=~\"$job\", instance=~\"$instance\"})", + "instant": false, + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Upstream Queries", + "type": "stat" + }, + { + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "noValue": "0%", + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "percentunit" + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 6, + "x": 12, + "y": 1 + }, + "id": 17, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "mean" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.4", + "targets": [ + { + "expr": "sum(dnsmasq_servers_queries_failed{job=~\"$job\", instance=~\"$instance\"}) / sum(dnsmasq_servers_queries{job=~\"$job\", instance=~\"$instance\"})", + "instant": false, + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Upstream Failed Queries", + "type": "stat" + }, + { + "collapsed": false, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 7 + }, + "id": 13, + "panels": [], + "title": "Build Info", + "type": "row" + }, + { + "datasource": "prometheus", + "fieldConfig": { + "defaults": { + "custom": { + "align": null + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 24, + "x": 0, + "y": 8 + }, + "id": 4, + "options": { + "showHeader": true + }, + "pluginVersion": "7.0.4", + "targets": [ + { + "expr": "dnsmasq_exporter_build_info{job=~\"$job\", instance=~\"$instance\"}", + "format": "time_series", + "instant": true, + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "", + "transformations": [ + { + "id": "labelsToFields", + "options": {} + }, + { + "id": "organize", + "options": { + "excludeByName": { + "Time": true, + "Value": true, + "instance": false, + "job": true + }, + "indexByName": { + "Time": 5, + "Value": 7, + "branch": 4, + "goversion": 2, + "instance": 0, + "job": 6, + "revision": 3, + "version": 1 + }, + "renameByName": {} + } + } + ], + "type": "table" + }, + { + "collapsed": false, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 14 + }, + "id": 11, + "panels": [], + "title": "Cache Stats", + "type": "row" + }, + { + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 6, + "x": 0, + "y": 15 + }, + "id": 8, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "mean" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.4", + "targets": [ + { + "expr": "sum(dnsmasq_cachesize{job=~\"$job\", instance=~\"$instance\"})", + "instant": false, + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Cache Size", + "type": "stat" + }, + { + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 6, + "x": 6, + "y": 15 + }, + "id": 6, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "mean" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.4", + "targets": [ + { + "expr": "sum(dnsmasq_hits{job=~\"$job\", instance=~\"$instance\"})", + "instant": false, + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Cache Hits", + "type": "stat" + }, + { + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 6, + "x": 12, + "y": 15 + }, + "id": 9, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "mean" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.4", + "targets": [ + { + "expr": "sum(dnsmasq_hits{job=~\"$job\", instance=~\"$instance\"})", + "instant": false, + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Cache Hits", + "type": "stat" + }, + { + "datasource": "$datasource", + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 6, + "x": 18, + "y": 15 + }, + "id": 7, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "mean" + ], + "fields": "", + "values": false + } + }, + "pluginVersion": "7.0.4", + "targets": [ + { + "expr": "sum(dnsmasq_insertions{job=~\"$job\", instance=~\"$instance\"})", + "instant": false, + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Cache Insertions", + "type": "stat" + } + ], + "schemaVersion": 25, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "current": { + "selected": true, + "text": "prometheus", + "value": "prometheus" + }, + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "datasource", + "options": [], + "query": "prometheus", + "queryValue": "", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "type": "datasource" + }, + { + "allValue": null, + "current": { + "selected": true, + "text": "dnsmasq", + "value": [ + "dnsmasq" + ] + }, + "datasource": "$datasource", + "definition": "label_values(dnsmasq_exporter_build_info, job)", + "hide": 0, + "includeAll": true, + "label": null, + "multi": true, + "name": "job", + "options": [ + { + "selected": false, + "text": "All", + "value": "$__all" + }, + { + "selected": true, + "text": "dnsmasq", + "value": "dnsmasq" + } + ], + "query": "label_values(dnsmasq_exporter_build_info, job)", + "refresh": 0, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + "selected": true, + "text": "router.lan", + "value": [ + "router.lan" + ] + }, + "datasource": "$datasource", + "definition": "label_values(dnsmasq_exporter_build_info, instance)", + "hide": 0, + "includeAll": true, + "label": null, + "multi": true, + "name": "instance", + "options": [ + { + "selected": false, + "text": "All", + "value": "$__all" + }, + { + "selected": true, + "text": "router.lan", + "value": "router.lan" + } + ], + "query": "label_values(dnsmasq_exporter_build_info, instance)", + "refresh": 0, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ] + }, + "timezone": "", + "title": "dnsmasq", + "uid": "ySypWTcMk", + "version": 2 +} \ No newline at end of file diff --git a/dnsmasq-mixin/go.mod b/dnsmasq-mixin/go.mod new file mode 100644 index 0000000..58c1af8 --- /dev/null +++ b/dnsmasq-mixin/go.mod @@ -0,0 +1,9 @@ +module github.com/google/dnsmasq_exporter/dnsmasq-mixin + +go 1.14 + +require ( + github.com/campoy/embedmd v1.0.0 // indirect + github.com/google/go-jsonnet v0.16.0 // indirect + github.com/monitoring-mixins/mixtool v0.0.0-20201009093517-e5001c032796 // indirect +) diff --git a/dnsmasq-mixin/mixin.libsonnet b/dnsmasq-mixin/mixin.libsonnet new file mode 100644 index 0000000..804b677 --- /dev/null +++ b/dnsmasq-mixin/mixin.libsonnet @@ -0,0 +1,5 @@ +{ + grafanaDashboards: { + 'dnsmasq-overview.json': (import 'dnsmasq-overview.json'), + }, +}