A tool to lint Grafana dashboards

Overview

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.

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.

    opened by sdboyer 11
  • 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]

    opened by arajkumar 9
  • 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

    opened by wuzuf 5
  • 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

    opened by wuzuf 5
  • 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

    opened by mshahzeb 3
  • 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?

    opened by wuzuf 3
  • 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

    opened by wuzuf 3
  • 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

    opened by mshahzeb 2
  • 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)
    dependencies 
    opened by dependabot[bot] 2
  • 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)
    dependencies 
    opened by dependabot[bot] 2
  • 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": ""
    }
    
    opened by antoniocascais 2
  • 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.

    opened by rgeyer 0
  • 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.

    opened by mshahzeb 0
  • Multi-select best practices

    Multi-select best practices

    When a template variable has multi set to true, it should also have an allValue defined as .+. This check is performed on job and instance, but always requires those template vars to be multi select.

    When a query includes a template variable that is multiselect, it must always be queried with regex matching, I.E. some_label=~"$some_template_var"

    opened by rgeyer 1
  • Non-Prometheus support (or at least exclusion)

    Non-Prometheus support (or at least exclusion)

    When linting a dashboard which does not use prometheus targets, several linting errors will be returned.

    These are not actually errors, they're just prometheus based rules being applied to non-prometheus targets and dashboards.

    The linter should allow rules to opt-in to what type of panels/targets it can effectively evaluate for best practice, and simply ignore the rest.

    This would mean that running the dashboard linter against a dashboard for which it has no best practices (such as query specific rules for a loki panel, as an example), no errors would be emitted.

    In time, this would allow for rules specific to other datasources to be added.

    opened by rgeyer 0
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
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

Petr 18 Apr 6, 2021
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

unsafecast 35 Jul 21, 2022
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

Schwarz IT 77 Sep 18, 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.

Multi-Cloud Object Storage 18 Sep 16, 2022
A TinySQL deployment tool inspired by TiUP

A TinySQL deployment tool inspired by TiUP

null 3 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.

Valérie 0 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.

null 8 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

David Chase 0 Feb 1, 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

Maksym Postument 161 Sep 18, 2022
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

Michelin 33 Sep 4, 2022
Languagetool-lint - Lint tool for languagetool

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

skanehira 9 Sep 4, 2022
helm-lint-ls is helm lint language server protocol LSP.

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

MrJosh 17 Sep 23, 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

Kévin Gomez 471 Sep 23, 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

Xabier Larrakoetxea Gallego 785 Sep 23, 2022
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

Izak Marais 779 Sep 25, 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

Nicolas Takashi 40 Jul 21, 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

Novatec Consulting GmbH 6 Apr 8, 2022
Terraform-grafana-dashboard - Grafana dashboard Terraform module

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

hadenlabs 1 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

Péter Szilágyi 2 Feb 13, 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

Ammar Bandukwala 4 Feb 8, 2022