A tool to lint Grafana dashboards

Grafana Dashboard Linter

This is a tool to lint Grafana dashboards for common mistakes. To use:

$ go install github.com/grafana/dashboard-linter
$ dashboard-linter lint dashboard.json

This tool is a work in progress, and its very early days. Right now its focused exclusively on dashboards that use a Prometheus datasource.

Owner
Grafana Labs
Grafana Labs is behind leading open source projects Grafana and Loki, and the creator of the first open & composable observability platform.
Grafana Labs
Comments
  • Add rule for validating dashboards

    Add rule for validating dashboards

    This adds rules for validating the dashboards using the official upstream schema.

    I've marked this as a draft because, after having seen how the flow of this tool actually works, it seems like a sloppy way to integrate this kind of logic - the possibility of false positives, and the messiness of errors, make it maaaaaaybe a good addition (it's good enough that we no longer allow Grafana dashboards to enter grafana/grafana/devenv without passing validation), but still not completely canonical and reliable. OTOH, that isn't worse than e.g. false positives arising from expecting only Prom queries.

    Either way, i figured it was worth putting the PR up at minimum to show how this kind of addition could be made. My guess is that a larger refactor of the application to treat validation as a prerequisite to linting would be a better architecture, and would also probably set us up for when we have Go structs that represent dashboard structures.

  • Allow template variable substitution in panel promql

    Allow template variable substitution in panel promql

    As mentioned in the $title, this PR enables templated variable substitution in panel promql expressions.

    Example: https://github.com/kubernetes-monitoring/kubernetes-mixin/blob/master/dashboards/network-usage/cluster-total.libsonnet#L395

    Signed-off-by: Arunprasad Rajkumar [email protected]

  • Add the possibility to add custom rules implemented in Go

    Add the possibility to add custom rules implemented in Go

    Hello, I my company, we have a rule that the first panel of a dashboard should be named "Dashboard Info" and should contain some panels with PoC, ... I was hoping, thanks to this PR to replace my current jq based solution with a Custom Rule integrated to the linter. My intent is to gather feedback on the idea. Before merging I would like to add some test cases, to at least validate the case when a rule implements several interfaces (dashboard, panel, target linter). Thanks again in advance for your inputs Gabriel

  • Use template variables to expand variables in promQL expressions

    Use template variables to expand variables in promQL expressions

    Another solution to the problem shared in https://github.com/grafana/dashboard-linter/pull/18 Tested successfully on the HEAD of https://github.com/kubernetes-monitoring/kubernetes-mixin.git (removing the sed line in the Makefile) @tomwilkie @arajkumar

  • Add rule to check default time and refresh interval

    Add rule to check default time and refresh interval

    Reference issue: https://github.com/grafana/dashboard-linter/issues/52

    This rule checks if each dashboard has:

    • A default time interval of 1h
    • A default refresh interval of 5m

    image

  • Check code if gofmt'ed

    Check code if gofmt'ed

    Add a linter to golangci-lint (first build will check to validate it actually works). Then I will format the code to make it pass.

    Btw, in another project I use this setup: linters: enable: - bodyclose - deadcode - errcheck - goconst - gocritic - goerr113 - gofmt - goprintffuncname - gosec - gosimple - govet - ineffassign - misspell - nakedret - nolintlint - prealloc - exportloopref - staticcheck - structcheck - testpackage - unconvert - unused - varcheck - whitespace - gocognit - godox - ifshort - importas - forbidigo

    linters-settings: gocognit: min-complexity: 15 forbidigo: forbid: - ^print.$ - 'fmt.Print.'

    @tomwilkie , do you want me to explore activating those too?

  • Check $__rate_interval only for rate functions

    Check $__rate_interval only for rate functions

    Hello, This should cover a case I have internally, with a query like sum(increase(foo{...}[$__range])) interval, which I believe should not be rejected by the linter. Let me know if you have concerns. Gabriel

  • Adds rule to check if each panel has valid units assigned

    Adds rule to check if each panel has valid units assigned

    Reference issue: https://github.com/grafana/dashboard-linter/issues/51

    This rule checks that each panel must have a valid unit assigned. The unit is extracted from dashboard json in the following manner:

    • Parse overrides to check if any override unit is present
    • If no overrride unit - then extract standard option unit
    • Check if unit is defined and is valid

    Valid units are extracted from here: https://github.com/grafana/grafana/blob/main/packages/grafana-data/src/valueFormats/categories.ts

    Considerations:

    • For a panel with multiple fields and panels - the last override unit will be picked

    Sample output: image

  • Bump github.com/prometheus/prometheus from 0.36.0 to 0.36.1

    Bump github.com/prometheus/prometheus from 0.36.0 to 0.36.1

    Bumps github.com/prometheus/prometheus from 0.36.0 to 0.36.1.

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
  • Bump github.com/stretchr/testify from 1.7.1 to 1.7.2

    Bump github.com/stretchr/testify from 1.7.1 to 1.7.2

    Bumps github.com/stretchr/testify from 1.7.1 to 1.7.2.

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
  • Linter throws an error when dashboard has multiple choice variables

    Linter throws an error when dashboard has multiple choice variables

    Summary of the issue

    When you have a multiple choice variable in your dashboard, linter will throw an error.

    Cause of the issue

    TemplateValue struct is expecting 2 fields as string (https://github.com/grafana/dashboard-linter/blob/main/lint/lint.go#L35), but multiple choice variables are arrays:

      "templating": {
        "list": [
          {
            "current": {
              "selected": true,
              "text": [
                "All"
              ],
              "value": [
                "$__all"
              ]
            },
    ...
    

    Expected behaviour

    Linter shouldn't throw an error when the dashboard has multiple choice variables.

    How to replicate

    Just add a multiple choice variable to your dashboard. For example

    {
      "annotations": {
        "list": [
          {
            "builtIn": 1,
            "datasource": "-- Grafana --",
            "enable": true,
            "hide": true,
            "iconColor": "rgba(0, 211, 255, 1)",
            "name": "Annotations & Alerts",
            "target": {
              "limit": 100,
              "matchAny": false,
              "tags": [],
              "type": "dashboard"
            },
            "type": "dashboard"
          }
        ]
      },
      "editable": true,
      "fiscalYearStartMonth": 0,
      "graphTooltip": 0,
      "iteration": 1649669111850,
      "links": [],
      "liveNow": false,
      "panels": [
        {
          "fieldConfig": {
            "defaults": {
              "color": {
                "mode": "palette-classic"
              },
              "custom": {
                "axisLabel": "",
                "axisPlacement": "auto",
                "barAlignment": 0,
                "drawStyle": "line",
                "fillOpacity": 0,
                "gradientMode": "none",
                "hideFrom": {
                  "legend": false,
                  "tooltip": false,
                  "viz": false
                },
                "lineInterpolation": "linear",
                "lineWidth": 1,
                "pointSize": 5,
                "scaleDistribution": {
                  "type": "linear"
                },
                "showPoints": "auto",
                "spanNulls": false,
                "stacking": {
                  "group": "A",
                  "mode": "none"
                },
                "thresholdsStyle": {
                  "mode": "off"
                }
              },
              "mappings": [],
              "thresholds": {
                "mode": "absolute",
                "steps": [
                  {
                    "color": "green",
                    "value": null
                  },
                  {
                    "color": "red",
                    "value": 80
                  }
                ]
              }
            },
            "overrides": []
          },
          "gridPos": {
            "h": 9,
            "w": 12,
            "x": 0,
            "y": 0
          },
          "id": 2,
          "options": {
            "legend": {
              "calcs": [],
              "displayMode": "list",
              "placement": "bottom"
            },
            "tooltip": {
              "mode": "single",
              "sort": "none"
            }
          },
          "title": "Panel Title",
          "type": "timeseries"
        }
      ],
      "refresh": "",
      "schemaVersion": 35,
      "style": "dark",
      "tags": [],
      "templating": {
        "list": [
          {
            "current": {
              "selected": true,
              "text": [
                "All"
              ],
              "value": [
                "$__all"
              ]
            },
            "hide": 0,
            "includeAll": true,
            "label": "Variable",
            "multi": true,
            "name": "query0",
            "options": [
              {
                "selected": true,
                "text": "All",
                "value": "$__all"
              },
              {
                "selected": false,
                "text": "foo",
                "value": "foo"
              },
              {
                "selected": false,
                "text": "bar",
                "value": "bar"
              }
            ],
            "query": "foo,bar",
            "queryValue": "",
            "skipUrlSync": false,
            "type": "custom"
          }
        ]
      },
      "time": {
        "from": "now-6h",
        "to": "now"
      },
      "timepicker": {},
      "timezone": "",
      "title": "New dashboard",
      "version": 0,
      "weekStart": ""
    }
    
  • grafana panel

    grafana panel

    Architecture. telegraf+influxdb+grafana Requirements. Is there a statistics panel to display server information, e.g., 20 servers in total, 4 abnormal and the rest normal.

    image

  • Dashboard variable with type prometheus without $dashboard is not flagged by linter

    Dashboard variable with type prometheus without $dashboard is not flagged by linter

    Dashboard variable like below is not flagged by linter. You can see that UID is assigned specific value pjNv0fYGz. Such dashboard is not portable across different grafana environments. It would be nice for a linter to flag such case.

          {¬
            "current": {¬
              "selected": false,¬
              "text": "X",¬
              "value": "X"¬
            },¬
            "datasource": {¬
              "type": "prometheus",¬
              "uid": "pjNv0fYGz"¬
            },¬
            "definition": "definition",¬
            "hide": 0,¬
            "includeAll": false,¬
            "label": "Customer ID",¬
            "multi": false,¬
            "name": "customerid",¬
            "options": [],¬
            "query": {¬
              "query": "PromQL",¬
              "refId": "StandardVariableQuery"¬
            },¬
            "refresh": 2,¬
            "regex": "",¬
            "skipUrlSync": false,¬
            "sort": 0,¬
            "type": "query"¬
          }
    
  • Constant template should not be flagged by linter

    Constant template should not be flagged by linter

    I have a constant variable in a dashboard and it looks like it gets flagged by linter

         {
            "hide": 2,¬
            "name": "instance",¬
            "query": ".*",¬
            "skipUrlSync": false,¬
            "type": "constant"¬
          }
    
    $HOME/go/bin/dashboard-linter lint mydashboard.json
    
    [❌] Dashboard 'My dashboard' instance template should use datasource '$datasource', is currently ''
    

    Should it be?

  • Add target histogram rule

    Add target histogram rule

    Resolves #56.

    Fairly simple, and literal check that finds any metric/series containing _bucket and ensures that it is inside of a function call to histogram_quantile.

    There was some internal slack discussion about forthcoming features which may need to be accounted for in the future, but we will wait until those are finalized before addressing them in the rules.

  • Any query having a multi=true template variable should be aggregated

    Any query having a multi=true template variable should be aggregated

    All the queries that use a template variable which allows multiselection should be aggregated:

    • Either by using an aggregator function in PromQL or LogQL
    • Or by using an aggregation option from the Grafana panel options

    This will avoid a situation where we see multiple repeating values unintentionally in a panel like "Single stat".

    This rule should also be limited to stat or panels that are used to show aggregated stats.

cmd tool for automatic storage and comparison of benchmarks results

prettybenchcmp prettybenchcmp is cmd tool for storage and comparison of benchmarks results. There is a standard tool benchcmp, but I don't think that

Apr 6, 2021
A tool that helps you write code in your favorite IDE: your word processor!
A tool that helps you write code in your favorite IDE: your word processor!

WordIDE Have you ever wondered: How would it feel like to write code in a word processor? Me neither. But after months minutes of planning, I present

Jul 21, 2022
go/template is a tool for jumpstarting production-ready Golang projects quickly.
go/template is a tool for jumpstarting production-ready Golang projects quickly.

go/template go/template provides a blueprint for production-ready Go project layouts. Credit to Renée French for the Go Gopher logo Credit to Go Autho

Dec 24, 2022
Drive performance measurement tool

dperf is a drive performance measurement tool to identify slow drives in your host. It takes multiple file paths as input, and performs I/O parallely on those files. The read and write throughput are printed in sorted order, with the fastest drives shown first.

Nov 23, 2022
A TinySQL deployment tool inspired by TiUP

A TinySQL deployment tool inspired by TiUP

Jan 26, 2022
Simple tool that updates Visual Studio Code workspace(s) to include Go modules in gopath/src, then launches VSCode if only one modified.

Simple tool that updates Visual Studio Code workspace(s) to include Go modules in gopath/src, then launches VSCode if only one modified.

Jan 27, 2022
ide-gen is a tool for development workspace prepare automation by automatic VCS repositories discovery and clone and project generation for supported IDEs.

ide-gen is a tool for development workspace prepare automation by automatic VCS repositories discovery and clone and project generation for supported IDEs.

May 8, 2022
A small tool that allows a process to ask a debugger to attach to it.

Client and server for a process to request attach by gdlv. These two packages allow a program to request that a debugger attach to it. The motivating

Feb 1, 2022
Languagetool-lint - Lint tool for languagetool

languagetool-lint Lint tool for languagetool. Requirements languagetool. Install

Oct 31, 2022
helm-lint-ls is helm lint language server protocol LSP.

helm-lint-ls is helm lint language server protocol LSP.

Dec 27, 2022
grafana-sync Keep your grafana dashboards in sync.

grafana-sync Keep your grafana dashboards in sync. Table of Contents grafana-sync Table of Contents Installing Getting Started Pull Save all dashboard

Dec 14, 2022
Snowflake grafana datasource plugin allows Snowflake data to be visually represented in Grafana dashboards.
Snowflake grafana datasource plugin allows Snowflake data to be visually represented in Grafana dashboards.

Snowflake Grafana Data Source With the Snowflake plugin, you can visualize your Snowflake data in Grafana and build awesome chart. Get started with th

Dec 29, 2022
User-friendly Go library for building Grafana dashboards

Grabana Grabana provides a developer-friendly way of creating Grafana dashboards. Whether you prefer writing code or YAML, if you are looking for a wa

Dec 16, 2022
Metrics dashboards on terminal (a grafana inspired terminal version)

Grafterm Visualize metrics dashboards on the terminal, like a simplified and minimalist version of Grafana for terminal. Features Multiple widgets (gr

Jan 6, 2023
A simple http service that generates *.PDF reports from Grafana dashboards.
A simple http service that generates *.PDF reports from Grafana dashboards.

Grafana reporter A simple http service that generates *.PDF reports from Grafana dashboards. Requirements Runtime requirements pdflatex installed and

Dec 27, 2022
Cole - Cole can use his sixth sense to give you metrics about your Grafana dashboards

Cole Cole can use his sixth sense to give you metrics about your Grafana dashboa

Nov 9, 2022
A Grafana backend plugin for automatic synchronization of dashboard between multiple Grafana instances.

Grafana Dashboard Synchronization Backend Plugin A Grafana backend plugin for automatic synchronization of dashboard between multiple Grafana instance

Dec 23, 2022
Terraform-grafana-dashboard - Grafana dashboard Terraform module

terraform-grafana-dashboard terraform-grafana-dashboard for project Requirements

May 2, 2022
Grafana-threema-forwarder - Alert forwarder from Grafana webhooks to Threema wire messages

Grafana to Threema alert forwarder Although Grafana has built in support for pus

Nov 11, 2022
Superlint is an experimental, language-agnostic framework for lint rules written in Go.

superlint superlint is an experimental, language-agnostic framework for lint rules written in Go. superlint is designed to be a superset of all possib

Feb 8, 2022