From 95822e3173e46b31d785e1b2b9ce7b2cca23598d Mon Sep 17 00:00:00 2001 From: Fiona Liao Date: Wed, 9 Dec 2020 17:51:14 +0000 Subject: [PATCH 01/10] Add mixin with rough dashboard Dashboard is currently in JSON and has test data. --- github-mixin/.gitignore | 3 + github-mixin/README.md | 2 + github-mixin/dashboards/github-overview.json | 713 +++++++++++++++++++ github-mixin/mixin.libsonnet | 5 + 4 files changed, 723 insertions(+) create mode 100644 github-mixin/.gitignore create mode 100644 github-mixin/README.md create mode 100644 github-mixin/dashboards/github-overview.json create mode 100644 github-mixin/mixin.libsonnet diff --git a/github-mixin/.gitignore b/github-mixin/.gitignore new file mode 100644 index 00000000..56b93f92 --- /dev/null +++ b/github-mixin/.gitignore @@ -0,0 +1,3 @@ +/alerts.yaml +/rules.yaml +dashboards_out \ No newline at end of file diff --git a/github-mixin/README.md b/github-mixin/README.md new file mode 100644 index 00000000..340b3f96 --- /dev/null +++ b/github-mixin/README.md @@ -0,0 +1,2 @@ +TODO +Mixin for GitHub exporter. Generates dashboard, with ability to generate rules and alerts. \ No newline at end of file diff --git a/github-mixin/dashboards/github-overview.json b/github-mixin/dashboards/github-overview.json new file mode 100644 index 00000000..8ff1a9b3 --- /dev/null +++ b/github-mixin/dashboards/github-overview.json @@ -0,0 +1,713 @@ +{ + "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": 1, + "iteration": 1607535589600, + "links": [], + "panels": [ + { + "collapsed": false, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 14, + "panels": [], + "repeat": "repo", + "title": "$repo", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": null, + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 9, + "x": 0, + "y": 1 + }, + "hiddenSeries": false, + "id": 9, + "legend": { + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.2.0", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "github_repo_open_issues{repo=\"$repo\"} ", + "instant": false, + "interval": "", + "legendFormat": "open issues", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Open Issues", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "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": null, + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 9, + "x": 9, + "y": 1 + }, + "hiddenSeries": false, + "id": 10, + "legend": { + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.2.0", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "github_repo_pull_request_count{repo=\"$repo\"} ", + "interval": "", + "legendFormat": "open prs", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Open Pull Requests", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "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": null, + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 9, + "x": 0, + "y": 8 + }, + "hiddenSeries": false, + "id": 11, + "legend": { + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.2.0", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "github_repo_forks{repo=\"$repo\"} ", + "interval": "", + "legendFormat": "forks", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Forks", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "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": null, + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 9, + "x": 9, + "y": 8 + }, + "hiddenSeries": false, + "id": 12, + "legend": { + "avg": true, + "current": true, + "max": true, + "min": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.2.0", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "github_repo_stars{repo=\"$repo\"} ", + "interval": "", + "legendFormat": "stars", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Stars", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "collapsed": false, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 15 + }, + "id": 4, + "panels": [], + "title": "API Limits", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": null, + "description": "The exporter uses the GitHub API to emit metrics, which has a rate limit. If this throttles, additional metrics will not be emitted.", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 9, + "x": 0, + "y": 16 + }, + "hiddenSeries": false, + "id": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.2.0", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "github_rate_limit", + "interval": "", + "legendFormat": "Limit", + "refId": "A" + }, + { + "expr": "github_rate_remaining", + "interval": "", + "legendFormat": "Remaining", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "datasource": null, + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "blue", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 9, + "y": 16 + }, + "id": 6, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "center", + "orientation": "vertical", + "reduceOptions": { + "calcs": [ + "last" + ], + "fields": "", + "values": false + }, + "textMode": "value" + }, + "pluginVersion": "7.2.0", + "targets": [ + { + "expr": "github_rate_limit", + "format": "time_series", + "instant": false, + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Limit", + "type": "stat" + }, + { + "datasource": null, + "fieldConfig": { + "defaults": { + "custom": {}, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "dark-red", + "value": null + }, + { + "color": "green", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 9, + "y": 20 + }, + "id": 7, + "options": { + "colorMode": "value", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "vertical", + "reduceOptions": { + "calcs": [ + "last" + ], + "fields": "", + "values": false + }, + "textMode": "value" + }, + "pluginVersion": "7.2.0", + "targets": [ + { + "expr": "github_rate_remaining", + "format": "time_series", + "instant": false, + "interval": "", + "legendFormat": "", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Remaining", + "type": "stat" + } + ], + "schemaVersion": 26, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "allValue": null, + "current": { + "selected": true, + "tags": [], + "text": [], + "value": [] + }, + "datasource": "Prometheus", + "definition": "label_values(repo)", + "hide": 0, + "includeAll": false, + "label": null, + "multi": true, + "name": "repo", + "options": [ + { + "selected": false, + "text": "agent", + "value": "agent" + }, + { + "selected": false, + "text": "cortex", + "value": "cortex" + }, + { + "selected": false, + "text": "github-exporter", + "value": "github-exporter" + }, + { + "selected": false, + "text": "grafana", + "value": "grafana" + } + ], + "query": "label_values(repo)", + "refresh": 0, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-24h", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "GitHub", + "uid": "lSZvN4JGz", + "version": 9 + } \ No newline at end of file diff --git a/github-mixin/mixin.libsonnet b/github-mixin/mixin.libsonnet new file mode 100644 index 00000000..cd96c923 --- /dev/null +++ b/github-mixin/mixin.libsonnet @@ -0,0 +1,5 @@ +{ + grafanaDashboards: { + 'github-overview.json': (import 'dashboards/github-overview.json'), + }, +} \ No newline at end of file From 803e23838f8e5176cbe9904635bafbcd6a938080 Mon Sep 17 00:00:00 2001 From: Fiona Liao Date: Wed, 9 Dec 2020 18:07:59 +0000 Subject: [PATCH 02/10] Add README and Makefile for mixin --- github-mixin/Makefile | 23 +++++++++++++++++++++++ github-mixin/README.md | 20 ++++++++++++++++++-- 2 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 github-mixin/Makefile diff --git a/github-mixin/Makefile b/github-mixin/Makefile new file mode 100644 index 00000000..4b054163 --- /dev/null +++ b/github-mixin/Makefile @@ -0,0 +1,23 @@ +JSONNET_FMT := jsonnetfmt -n 2 --max-blank-lines 2 --string-style s --comment-style s + +default: build + +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 dashboards mixin.libsonnet -d dashboards_out + +clean: + rm -rf dashboards_out \ No newline at end of file diff --git a/github-mixin/README.md b/github-mixin/README.md index 340b3f96..7a0c4a4d 100644 --- a/github-mixin/README.md +++ b/github-mixin/README.md @@ -1,2 +1,18 @@ -TODO -Mixin for GitHub exporter. Generates dashboard, with ability to generate rules and alerts. \ No newline at end of file +# GitHub Mixin + +The GitHub Mixin is a set of configurable, reusable, and extensible dashboards based on the metrics exported by the GitHub Exporter. The mixin creates 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 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. + +The mixin can be extended with recording and alerting rules for Prometheus. \ No newline at end of file From fe315c3ab30f934c1a3899fdb36da614e6869380 Mon Sep 17 00:00:00 2001 From: Fiona Liao Date: Thu, 10 Dec 2020 10:05:05 +0000 Subject: [PATCH 03/10] Add mixin tests to Travis config Also fixed whitespace causing mixin linting to fail. --- .travis.yml | 6 ++++++ github-mixin/mixin.libsonnet | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 1a0ae8e1..6db4a725 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,10 +3,16 @@ language: go go: - "1.14" +before_script: + # For mixin + - go install github.com/monitoring-mixins/mixtool/cmd/mixtool + - go install github.com/google/go-jsonnet/cmd/jsonnetfmt + script: - diff -u <(echo -n) <(gofmt -s -d ./) - diff -u <(echo -n) <(go vet ./...) - go test -v ./... + - make -C github-mixin lint build env: - GO111MODULE=on diff --git a/github-mixin/mixin.libsonnet b/github-mixin/mixin.libsonnet index cd96c923..ce354d40 100644 --- a/github-mixin/mixin.libsonnet +++ b/github-mixin/mixin.libsonnet @@ -2,4 +2,4 @@ grafanaDashboards: { 'github-overview.json': (import 'dashboards/github-overview.json'), }, -} \ No newline at end of file +} From 728d3fda25f1d2a31e8167f54003274b1517f7b0 Mon Sep 17 00:00:00 2001 From: Fiona Liao Date: Mon, 14 Dec 2020 19:47:31 +0000 Subject: [PATCH 04/10] Add user label to PR metric Previously, only the repo label was added to the pull request metric. Multiple repositories can have the same repo value - the user label is required to uniquely identify a GitHub repository. --- exporter/metrics.go | 11 +++++++---- test/github_exporter_test.go | 13 +++++++------ 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/exporter/metrics.go b/exporter/metrics.go index 3bd3c161..679b2a0b 100644 --- a/exporter/metrics.go +++ b/exporter/metrics.go @@ -1,7 +1,10 @@ package exporter -import "github.com/prometheus/client_golang/prometheus" -import "strconv" +import ( + "strconv" + + "github.com/prometheus/client_golang/prometheus" +) // AddMetrics - Add's all of the metrics to a map of strings, returns the map. func AddMetrics() map[string]*prometheus.Desc { @@ -21,7 +24,7 @@ func AddMetrics() map[string]*prometheus.Desc { APIMetrics["PullRequestCount"] = prometheus.NewDesc( prometheus.BuildFQName("github", "repo", "pull_request_count"), "Total number of pull requests for given repository", - []string{"repo"}, nil, + []string{"repo", "user"}, nil, ) APIMetrics["Watchers"] = prometheus.NewDesc( prometheus.BuildFQName("github", "repo", "watchers"), @@ -85,7 +88,7 @@ func (e *Exporter) processMetrics(data []*Datum, rates *RateLimits, ch chan<- pr ch <- prometheus.MustNewConstMetric(e.APIMetrics["OpenIssues"], prometheus.GaugeValue, (x.OpenIssues - float64(prCount)), x.Name, x.Owner.Login, strconv.FormatBool(x.Private), strconv.FormatBool(x.Fork), strconv.FormatBool(x.Archived), x.License.Key, x.Language) // prCount - ch <- prometheus.MustNewConstMetric(e.APIMetrics["PullRequestCount"], prometheus.GaugeValue, float64(prCount), x.Name) + ch <- prometheus.MustNewConstMetric(e.APIMetrics["PullRequestCount"], prometheus.GaugeValue, float64(prCount), x.Name, x.Owner.Login) } // Set Rate limit stats diff --git a/test/github_exporter_test.go b/test/github_exporter_test.go index e3d0fd1e..9e3f1e5c 100644 --- a/test/github_exporter_test.go +++ b/test/github_exporter_test.go @@ -2,16 +2,17 @@ package test import ( "fmt" - "github.com/infinityworks/github-exporter/config" - "github.com/infinityworks/github-exporter/exporter" - web "github.com/infinityworks/github-exporter/http" - "github.com/prometheus/client_golang/prometheus" - "github.com/steinfletcher/apitest" "io/ioutil" "net/http" "os" "strings" "testing" + + "github.com/infinityworks/github-exporter/config" + "github.com/infinityworks/github-exporter/exporter" + web "github.com/infinityworks/github-exporter/http" + "github.com/prometheus/client_golang/prometheus" + "github.com/steinfletcher/apitest" ) func TestHomepage(t *testing.T) { @@ -41,7 +42,7 @@ func TestGithubExporter(t *testing.T) { Assert(bodyContains(`github_rate_remaining 60`)). Assert(bodyContains(`github_rate_reset 1.566853865e+09`)). Assert(bodyContains(`github_repo_forks{archived="false",fork="false",language="Go",license="mit",private="false",repo="myRepo",user="myOrg"} 10`)). - Assert(bodyContains(`github_repo_pull_request_count{repo="myRepo"} 3`)). + Assert(bodyContains(`github_repo_pull_request_count{repo="myRepo",user="myOrg"} 3`)). Assert(bodyContains(`github_repo_open_issues{archived="false",fork="false",language="Go",license="mit",private="false",repo="myRepo",user="myOrg"} 2`)). Assert(bodyContains(`github_repo_size_kb{archived="false",fork="false",language="Go",license="mit",private="false",repo="myRepo",user="myOrg"} 946`)). Assert(bodyContains(`github_repo_stars{archived="false",fork="false",language="Go",license="mit",private="false",repo="myRepo",user="myOrg"} 120`)). From a685b2de4d28482bfc29150abbe8e3fd7f956e93 Mon Sep 17 00:00:00 2001 From: Fiona Liao Date: Mon, 14 Dec 2020 19:58:19 +0000 Subject: [PATCH 05/10] Use Jsonnet to define mixin dashboards Created a GitHub repository dashboard, which graphs exporter metrics for a given repository. Also created an API usage dashboard to check the if the exporter is running out of requests. The dashboards use Grafonnet, a library for writing Grafana dashboards. Added jsonnet-bundler integration so the Grafonnet package can be fetched. --- .travis.yml | 3 +- github-mixin/.gitignore | 4 +- github-mixin/Makefile | 7 +- github-mixin/README.md | 4 +- github-mixin/dashboards/api-usage.libsonnet | 41 + github-mixin/dashboards/common.libsonnet | 17 + github-mixin/dashboards/github-overview.json | 713 ------------------ .../dashboards/repository-stats.libsonnet | 91 +++ github-mixin/jsonnetfile.json | 15 + github-mixin/local-deploy.sh | 19 + github-mixin/mixin.libsonnet | 3 +- 11 files changed, 198 insertions(+), 719 deletions(-) create mode 100644 github-mixin/dashboards/api-usage.libsonnet create mode 100644 github-mixin/dashboards/common.libsonnet delete mode 100644 github-mixin/dashboards/github-overview.json create mode 100644 github-mixin/dashboards/repository-stats.libsonnet create mode 100644 github-mixin/jsonnetfile.json create mode 100644 github-mixin/local-deploy.sh diff --git a/.travis.yml b/.travis.yml index 6db4a725..902296b3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,6 +5,7 @@ go: before_script: # For mixin + - go install github.com/jsonnet-bundler/jsonnet-bundler/cmd/jb - go install github.com/monitoring-mixins/mixtool/cmd/mixtool - go install github.com/google/go-jsonnet/cmd/jsonnetfmt @@ -12,7 +13,7 @@ script: - diff -u <(echo -n) <(gofmt -s -d ./) - diff -u <(echo -n) <(go vet ./...) - go test -v ./... - - make -C github-mixin lint build + - make -C github-mixin lint install build env: - GO111MODULE=on diff --git a/github-mixin/.gitignore b/github-mixin/.gitignore index 56b93f92..77937f79 100644 --- a/github-mixin/.gitignore +++ b/github-mixin/.gitignore @@ -1,3 +1,5 @@ /alerts.yaml /rules.yaml -dashboards_out \ No newline at end of file +dashboards_out +vendor +jsonnetfile.lock.json \ No newline at end of file diff --git a/github-mixin/Makefile b/github-mixin/Makefile index 4b054163..232fa205 100644 --- a/github-mixin/Makefile +++ b/github-mixin/Makefile @@ -2,7 +2,7 @@ JSONNET_FMT := jsonnetfmt -n 2 --max-blank-lines 2 --string-style s --comment-st default: build -all: fmt lint build clean +all: fmt lint install build fmt: find . -name 'vendor' -prune -o -name '*.libsonnet' -print -o -name '*.jsonnet' -print | \ @@ -16,7 +16,10 @@ lint: mixtool lint mixin.libsonnet -build: +install: + jb install + +build: mixtool generate dashboards mixin.libsonnet -d dashboards_out clean: diff --git a/github-mixin/README.md b/github-mixin/README.md index 7a0c4a4d..d8585c94 100644 --- a/github-mixin/README.md +++ b/github-mixin/README.md @@ -1,9 +1,11 @@ # GitHub Mixin +## Overview The GitHub Mixin is a set of configurable, reusable, and extensible dashboards based on the metrics exported by the GitHub Exporter. The mixin creates 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: +To use them, you need to have `jb`, `mixtool` and `jsonnetfmt` installed. If you have a working Go development environment, it's easiest to run the following: ```bash +$ go get github.com/jsonnet-bundler/jsonnet-bundler/cmd/jb $ go get github.com/monitoring-mixins/mixtool/cmd/mixtool $ go get github.com/google/go-jsonnet/cmd/jsonnetfmt ``` diff --git a/github-mixin/dashboards/api-usage.libsonnet b/github-mixin/dashboards/api-usage.libsonnet new file mode 100644 index 00000000..f826c6f6 --- /dev/null +++ b/github-mixin/dashboards/api-usage.libsonnet @@ -0,0 +1,41 @@ +local common = import 'common.libsonnet'; +local grafana = import 'github.com/grafana/grafonnet-lib/grafonnet/grafana.libsonnet'; + +grafana.dashboard.new('GitHub API Usage', uid='github-api-usage', editable=true) +.addTemplate( + grafana.template.datasource( + 'datasource', + 'prometheus', + 'Prometheus' + ) +) +.addPanels( + [ + grafana.text.new('GitHub Request Limits', content=||| + GitHub metrics are generated by calling the GitHub API, which will throttle if too many requests are made in an + hour. When this happens, gaps will appear for the metrics. + + This dashboard monitors the API usage, so you can tell if you are running out of requests. If this does + become a problem, consider reducing the set of repositories being monitored or the number of metrics being + generated, in order to reduce the request rate. + |||) + + { gridPos: { x: 0, y: 0, w: 24, h: 4 } }, + + grafana.graphPanel.new( + 'API Usage', + min=0, + ) + .addTarget(grafana.prometheus.target('github_rate_remaining', legendFormat='Remaining Requests')) + .addTarget(grafana.prometheus.target('github_rate_limit', legendFormat='Max Requests')) + + { gridPos: { x: 8, y: 4, w: 16, h: 10 } }, + + common.latestSingleStatPanel('Current Remaining Requests in Time Window') + .addTarget(grafana.prometheus.target('github_rate_remaining')) + + { gridPos: { x: 0, y: 4, w: 8, h: 5 } }, + + common.latestSingleStatPanel('Current Max Requests Per Hour') + .addTarget(grafana.prometheus.target('github_rate_limit')) + + { gridPos: { x: 0, y: 4, w: 8, h: 5 } }, + + ] +) diff --git a/github-mixin/dashboards/common.libsonnet b/github-mixin/dashboards/common.libsonnet new file mode 100644 index 00000000..569ffb8a --- /dev/null +++ b/github-mixin/dashboards/common.libsonnet @@ -0,0 +1,17 @@ +local grafana = import 'github.com/grafana/grafonnet-lib/grafonnet/grafana.libsonnet'; + +{ + latestSingleStatPanel(title, format='none'):: + grafana.statPanel.new(title, reducerFunction='last', graphMode='none') + + { + fieldConfig: { + defaults: { + thresholds: { + mode: 'absolute', + steps: [], + }, + unit: format, + }, + }, + }, +} diff --git a/github-mixin/dashboards/github-overview.json b/github-mixin/dashboards/github-overview.json deleted file mode 100644 index 8ff1a9b3..00000000 --- a/github-mixin/dashboards/github-overview.json +++ /dev/null @@ -1,713 +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": 1, - "iteration": 1607535589600, - "links": [], - "panels": [ - { - "collapsed": false, - "datasource": null, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 0 - }, - "id": 14, - "panels": [], - "repeat": "repo", - "title": "$repo", - "type": "row" - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": null, - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 9, - "x": 0, - "y": 1 - }, - "hiddenSeries": false, - "id": 9, - "legend": { - "avg": true, - "current": true, - "max": true, - "min": true, - "show": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.2.0", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "github_repo_open_issues{repo=\"$repo\"} ", - "instant": false, - "interval": "", - "legendFormat": "open issues", - "refId": "A" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Open Issues", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": "0", - "show": true - }, - { - "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": null, - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 9, - "x": 9, - "y": 1 - }, - "hiddenSeries": false, - "id": 10, - "legend": { - "avg": true, - "current": true, - "max": true, - "min": true, - "show": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.2.0", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "github_repo_pull_request_count{repo=\"$repo\"} ", - "interval": "", - "legendFormat": "open prs", - "refId": "A" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Open Pull Requests", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": "0", - "show": true - }, - { - "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": null, - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 9, - "x": 0, - "y": 8 - }, - "hiddenSeries": false, - "id": 11, - "legend": { - "avg": true, - "current": true, - "max": true, - "min": true, - "show": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.2.0", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "github_repo_forks{repo=\"$repo\"} ", - "interval": "", - "legendFormat": "forks", - "refId": "A" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Forks", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": "0", - "show": true - }, - { - "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": null, - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 7, - "w": 9, - "x": 9, - "y": 8 - }, - "hiddenSeries": false, - "id": 12, - "legend": { - "avg": true, - "current": true, - "max": true, - "min": true, - "show": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.2.0", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "github_repo_stars{repo=\"$repo\"} ", - "interval": "", - "legendFormat": "stars", - "refId": "A" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "Stars", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": "0", - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "collapsed": false, - "datasource": null, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 15 - }, - "id": 4, - "panels": [], - "title": "API Limits", - "type": "row" - }, - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": null, - "description": "The exporter uses the GitHub API to emit metrics, which has a rate limit. If this throttles, additional metrics will not be emitted.", - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 8, - "w": 9, - "x": 0, - "y": 16 - }, - "hiddenSeries": false, - "id": 2, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.2.0", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "expr": "github_rate_limit", - "interval": "", - "legendFormat": "Limit", - "refId": "A" - }, - { - "expr": "github_rate_remaining", - "interval": "", - "legendFormat": "Remaining", - "refId": "B" - } - ], - "thresholds": [], - "timeFrom": null, - "timeRegions": [], - "timeShift": null, - "title": "", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": null, - "mode": "time", - "name": null, - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": "0", - "show": true - }, - { - "format": "short", - "label": null, - "logBase": 1, - "max": null, - "min": null, - "show": true - } - ], - "yaxis": { - "align": false, - "alignLevel": null - } - }, - { - "datasource": null, - "fieldConfig": { - "defaults": { - "custom": {}, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "blue", - "value": null - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 4, - "w": 3, - "x": 9, - "y": 16 - }, - "id": 6, - "options": { - "colorMode": "value", - "graphMode": "none", - "justifyMode": "center", - "orientation": "vertical", - "reduceOptions": { - "calcs": [ - "last" - ], - "fields": "", - "values": false - }, - "textMode": "value" - }, - "pluginVersion": "7.2.0", - "targets": [ - { - "expr": "github_rate_limit", - "format": "time_series", - "instant": false, - "interval": "", - "legendFormat": "", - "refId": "A" - } - ], - "timeFrom": null, - "timeShift": null, - "title": "Limit", - "type": "stat" - }, - { - "datasource": null, - "fieldConfig": { - "defaults": { - "custom": {}, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "dark-red", - "value": null - }, - { - "color": "green", - "value": 80 - } - ] - } - }, - "overrides": [] - }, - "gridPos": { - "h": 4, - "w": 3, - "x": 9, - "y": 20 - }, - "id": 7, - "options": { - "colorMode": "value", - "graphMode": "none", - "justifyMode": "auto", - "orientation": "vertical", - "reduceOptions": { - "calcs": [ - "last" - ], - "fields": "", - "values": false - }, - "textMode": "value" - }, - "pluginVersion": "7.2.0", - "targets": [ - { - "expr": "github_rate_remaining", - "format": "time_series", - "instant": false, - "interval": "", - "legendFormat": "", - "refId": "A" - } - ], - "timeFrom": null, - "timeShift": null, - "title": "Remaining", - "type": "stat" - } - ], - "schemaVersion": 26, - "style": "dark", - "tags": [], - "templating": { - "list": [ - { - "allValue": null, - "current": { - "selected": true, - "tags": [], - "text": [], - "value": [] - }, - "datasource": "Prometheus", - "definition": "label_values(repo)", - "hide": 0, - "includeAll": false, - "label": null, - "multi": true, - "name": "repo", - "options": [ - { - "selected": false, - "text": "agent", - "value": "agent" - }, - { - "selected": false, - "text": "cortex", - "value": "cortex" - }, - { - "selected": false, - "text": "github-exporter", - "value": "github-exporter" - }, - { - "selected": false, - "text": "grafana", - "value": "grafana" - } - ], - "query": "label_values(repo)", - "refresh": 0, - "regex": "", - "skipUrlSync": false, - "sort": 0, - "tagValuesQuery": "", - "tags": [], - "tagsQuery": "", - "type": "query", - "useTags": false - } - ] - }, - "time": { - "from": "now-24h", - "to": "now" - }, - "timepicker": {}, - "timezone": "", - "title": "GitHub", - "uid": "lSZvN4JGz", - "version": 9 - } \ No newline at end of file diff --git a/github-mixin/dashboards/repository-stats.libsonnet b/github-mixin/dashboards/repository-stats.libsonnet new file mode 100644 index 00000000..f6faa3da --- /dev/null +++ b/github-mixin/dashboards/repository-stats.libsonnet @@ -0,0 +1,91 @@ +local common = import 'common.libsonnet'; +local grafana = import 'github.com/grafana/grafonnet-lib/grafonnet/grafana.libsonnet'; + +local dashboardWidth = 24; + +local metric(metric_name, title, format='none') = { + name: metric_name, + title: title, + format: format, +}; + +local latestRepoStatPanel(metric) = + common.latestSingleStatPanel(metric.title, metric.format) + .addTarget(grafana.prometheus.target(metric.name + '{user=~"$user",repo=~"$repo"}')); + +local graphPanel(metric) = + grafana.graphPanel.new( + metric.title, + min=0, + legend_show=false, + format=metric.format + ) + .addTarget(grafana.prometheus.target(metric.name + '{user=~"$user",repo=~"$repo"}')); + +local setGridPos(panels, startY, panelWidth, panelHeight) = + if panelWidth > dashboardWidth then + error 'panelWidth cannot be larger than dashboardWidth' + else + local calculate(index) = { + gridPos: { + x: (index % std.floor(dashboardWidth / panelWidth)) * panelWidth, + y: startY + std.floor((index * panelWidth) / dashboardWidth), + w: panelWidth, + h: panelHeight, + }, + }; + + std.mapWithIndex(function(index, panel) panel + calculate(index), panels); + +local maxY(panels) = std.foldl(std.max, [p.gridPos.y + p.gridPos.h for p in panels], 0); + +local repoPanels(metrics) = + local statPanels = std.map(latestRepoStatPanel, metrics); + local statPanelsWithGridPos = setGridPos(statPanels, 0, 4, 4); + + local statPanelsMaxY = maxY(statPanelsWithGridPos); + + local graphRowPanel = { title: 'Graphs', type: 'row' }; + local graphRowPanelWithGridPos = setGridPos([graphRowPanel], statPanelsMaxY, dashboardWidth, 1); + + local graphPanels = std.map(graphPanel, metrics); + local graphPanelsWithGridPos = setGridPos(graphPanels, statPanelsMaxY + 1, 8, 8); + + std.flattenArrays([statPanelsWithGridPos, graphRowPanelWithGridPos, graphPanelsWithGridPos]); + +grafana.dashboard.new('GitHub Repository Stats', uid='github-repo-stats', editable=true) +.addTemplate( + grafana.template.datasource( + 'datasource', + 'prometheus', + 'Prometheus' + ) +) +.addTemplate( + grafana.template.new( + 'user', + '$datasource', + 'label_values(user)', + refresh='load' + ) +) +.addTemplate( + grafana.template.new( + 'repo', + '$datasource', + 'label_values(github_repo_open_issues{user="$user"}, repo)', + refresh='load' + ) +) +.addPanels( + repoPanels( + [ + metric('github_repo_open_issues', 'Open Issues'), + metric('github_repo_pull_request_count', 'Open Pull Requests'), + metric('github_repo_forks', 'Forks'), + metric('github_repo_stars', 'Stars'), + metric('github_repo_watchers', 'Watchers'), + metric('github_repo_size_kb', 'Repository Size', format='deckbytes'), + ] + ) +) diff --git a/github-mixin/jsonnetfile.json b/github-mixin/jsonnetfile.json new file mode 100644 index 00000000..93f3316e --- /dev/null +++ b/github-mixin/jsonnetfile.json @@ -0,0 +1,15 @@ +{ + "version": 1, + "dependencies": [ + { + "source": { + "git": { + "remote": "https://github.com/grafana/grafonnet-lib.git", + "subdir": "grafonnet" + } + }, + "version": "master" + } + ], + "legacyImports": true +} diff --git a/github-mixin/local-deploy.sh b/github-mixin/local-deploy.sh new file mode 100644 index 00000000..00fab21d --- /dev/null +++ b/github-mixin/local-deploy.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash +make + +payload="{\"dashboard\": $(jq . dashboards_out/api-usage.json), \"overwrite\": true}" + +curl -X POST $BASIC_AUTH \ + -H 'Content-Type: application/json' \ + -d "${payload}" \ + "http://admin:admin@localhost:3000/api/dashboards/db" + + +payload="{\"dashboard\": $(jq . dashboards_out/repository-stats.json), \"overwrite\": true}" + +curl -X POST $BASIC_AUTH \ + -H 'Content-Type: application/json' \ + -d "${payload}" \ + "http://admin:admin@localhost:3000/api/dashboards/db" + +echo "\n" \ No newline at end of file diff --git a/github-mixin/mixin.libsonnet b/github-mixin/mixin.libsonnet index ce354d40..3c60a926 100644 --- a/github-mixin/mixin.libsonnet +++ b/github-mixin/mixin.libsonnet @@ -1,5 +1,6 @@ { grafanaDashboards: { - 'github-overview.json': (import 'dashboards/github-overview.json'), + 'api-usage.json': (import 'dashboards/api-usage.libsonnet'), + 'repository-stats.json': (import 'dashboards/repository-stats.libsonnet'), }, } From b9d068931db3cc5adb70aed64779248a0e8b8914 Mon Sep 17 00:00:00 2001 From: Fiona Liao Date: Mon, 14 Dec 2020 20:18:41 +0000 Subject: [PATCH 06/10] Fix mixin install and lint order jb install has to be run before linting as the linter checks the dependency files exist. --- .travis.yml | 2 +- github-mixin/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 902296b3..7cf2b652 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,7 @@ script: - diff -u <(echo -n) <(gofmt -s -d ./) - diff -u <(echo -n) <(go vet ./...) - go test -v ./... - - make -C github-mixin lint install build + - make -C github-mixin install lint build env: - GO111MODULE=on diff --git a/github-mixin/Makefile b/github-mixin/Makefile index 232fa205..692bd21d 100644 --- a/github-mixin/Makefile +++ b/github-mixin/Makefile @@ -2,7 +2,7 @@ JSONNET_FMT := jsonnetfmt -n 2 --max-blank-lines 2 --string-style s --comment-st default: build -all: fmt lint install build +all: install fmt lint build fmt: find . -name 'vendor' -prune -o -name '*.libsonnet' -print -o -name '*.jsonnet' -print | \ From 3753c604b58268d129a2e46c0cc4a86c06b4e00f Mon Sep 17 00:00:00 2001 From: Fiona Liao Date: Mon, 14 Dec 2020 20:22:42 +0000 Subject: [PATCH 07/10] Remove local testing file and add newlines --- github-mixin/.gitignore | 2 +- github-mixin/Makefile | 2 +- github-mixin/local-deploy.sh | 19 ------------------- 3 files changed, 2 insertions(+), 21 deletions(-) delete mode 100644 github-mixin/local-deploy.sh diff --git a/github-mixin/.gitignore b/github-mixin/.gitignore index 77937f79..ac3d221c 100644 --- a/github-mixin/.gitignore +++ b/github-mixin/.gitignore @@ -2,4 +2,4 @@ /rules.yaml dashboards_out vendor -jsonnetfile.lock.json \ No newline at end of file +jsonnetfile.lock.json diff --git a/github-mixin/Makefile b/github-mixin/Makefile index 692bd21d..66cb8d89 100644 --- a/github-mixin/Makefile +++ b/github-mixin/Makefile @@ -23,4 +23,4 @@ build: mixtool generate dashboards mixin.libsonnet -d dashboards_out clean: - rm -rf dashboards_out \ No newline at end of file + rm -rf dashboards_out diff --git a/github-mixin/local-deploy.sh b/github-mixin/local-deploy.sh deleted file mode 100644 index 00fab21d..00000000 --- a/github-mixin/local-deploy.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env bash -make - -payload="{\"dashboard\": $(jq . dashboards_out/api-usage.json), \"overwrite\": true}" - -curl -X POST $BASIC_AUTH \ - -H 'Content-Type: application/json' \ - -d "${payload}" \ - "http://admin:admin@localhost:3000/api/dashboards/db" - - -payload="{\"dashboard\": $(jq . dashboards_out/repository-stats.json), \"overwrite\": true}" - -curl -X POST $BASIC_AUTH \ - -H 'Content-Type: application/json' \ - -d "${payload}" \ - "http://admin:admin@localhost:3000/api/dashboards/db" - -echo "\n" \ No newline at end of file From 3534c04eb343367afa55b25700f0b68eca7a57fb Mon Sep 17 00:00:00 2001 From: Fiona Liao Date: Tue, 15 Dec 2020 09:44:32 +0000 Subject: [PATCH 08/10] Fix gridPos y calculation --- github-mixin/dashboards/repository-stats.libsonnet | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/github-mixin/dashboards/repository-stats.libsonnet b/github-mixin/dashboards/repository-stats.libsonnet index f6faa3da..697bafbd 100644 --- a/github-mixin/dashboards/repository-stats.libsonnet +++ b/github-mixin/dashboards/repository-stats.libsonnet @@ -22,14 +22,19 @@ local graphPanel(metric) = ) .addTarget(grafana.prometheus.target(metric.name + '{user=~"$user",repo=~"$repo"}')); +// Calculates positions of an array of panels which have the same dimensions and +// should be displayed together. +// Assumes the area above startY has been "filled in" - Grafana moves panels up +// automatically if there is empty space. local setGridPos(panels, startY, panelWidth, panelHeight) = if panelWidth > dashboardWidth then error 'panelWidth cannot be larger than dashboardWidth' else + local panelsPerRow = std.floor(dashboardWidth / panelWidth); local calculate(index) = { gridPos: { - x: (index % std.floor(dashboardWidth / panelWidth)) * panelWidth, - y: startY + std.floor((index * panelWidth) / dashboardWidth), + x: (index % panelsPerRow) * panelWidth, + y: startY + (std.floor(index / panelsPerRow) * panelHeight), w: panelWidth, h: panelHeight, }, From 897cc91712a7314f856848b0bef4eefa20a743d4 Mon Sep 17 00:00:00 2001 From: Fiona Liao Date: Tue, 15 Dec 2020 09:54:49 +0000 Subject: [PATCH 09/10] Update mixin README Added dashboard descriptions to README and updated running instructions so Jsonnet libraries that are required by the build are installed. --- github-mixin/README.md | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/github-mixin/README.md b/github-mixin/README.md index d8585c94..a06dfb7e 100644 --- a/github-mixin/README.md +++ b/github-mixin/README.md @@ -1,7 +1,9 @@ # GitHub Mixin ## Overview -The GitHub Mixin is a set of configurable, reusable, and extensible dashboards based on the metrics exported by the GitHub Exporter. The mixin creates suitable dashboard descriptions for Grafana. +Mixins are a collection of configurable, reusable Prometheus rules, alerts and/or Grafana dashboards for a particular system, usually created by experts in that system. By applying them to Prometheus and Grafana, you can quickly set up appropriate monitoring for your systems. + +The GitHub mixin currently provides simple dashboards for visualizing GitHub metrics emitted by the exporter. To use them, you need to have `jb`, `mixtool` and `jsonnetfmt` installed. If you have a working Go development environment, it's easiest to run the following: ```bash @@ -12,9 +14,14 @@ $ go get github.com/google/go-jsonnet/cmd/jsonnetfmt You can then build a directory `dashboard_out` with the JSON dashboard files for Grafana: ```bash -$ make build +$ make all ``` For more advanced uses of mixins, see https://github.com/monitoring-mixins/docs. -The mixin can be extended with recording and alerting rules for Prometheus. \ No newline at end of file +## Dashboards +* GitHub Repository Stats - Graphs GitHub metrics for a given repository. Any repository monitored by the exporter can be selected on this dashboard. +* GitHub API Usage - GitHub enforces rate limiting on the API used by the exporter. This dashboard can be used to monitor if the exporter is running out of requests. + +## Future Development +The mixin can be extended with recording and alerting rules for Prometheus. From 8f86afe1dc3d78c59763fc854817ab6a26525c80 Mon Sep 17 00:00:00 2001 From: Fiona Liao Date: Tue, 15 Dec 2020 10:46:15 +0000 Subject: [PATCH 10/10] Fix API usage gridPos --- github-mixin/dashboards/api-usage.libsonnet | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/github-mixin/dashboards/api-usage.libsonnet b/github-mixin/dashboards/api-usage.libsonnet index f826c6f6..3312bed9 100644 --- a/github-mixin/dashboards/api-usage.libsonnet +++ b/github-mixin/dashboards/api-usage.libsonnet @@ -35,7 +35,7 @@ grafana.dashboard.new('GitHub API Usage', uid='github-api-usage', editable=true) common.latestSingleStatPanel('Current Max Requests Per Hour') .addTarget(grafana.prometheus.target('github_rate_limit')) + - { gridPos: { x: 0, y: 4, w: 8, h: 5 } }, + { gridPos: { x: 0, y: 9, w: 8, h: 5 } }, ] )