Building Grafana dashboard generator (part 1)

Building a project skeleton


Following on the previous blog post I decided to build something I called Grafana simple dashboard generator. The whole point of this is to have a single CLI utility to generate the most needed dashboard metrics in Grafana without spending too much time learning Prometheus queries and tweaking them.

Most people don't need sophisticated graphs or visualizations, we have a pretty good idea of what needs to be monitored and when it's too bad that we have to check what's going on, i.e. alerting.

In this post, I will show building project skeleton for this CLI utility. I decided to write it in Go with the help of the cobra module.

Code structure

So far the code contains 2 folders - cmd and dashboard.
Cmd is responsible for manipulation via CLI and the dashboard will contain logic for Grafana dashboard.


  ├── LICENSE
  ├── README.md
  ├── cmd
  │   ├── init.go
  │   └── root.go
  ├── dashboard
  │   └── dashboard.go
  ├── go.mod
  ├── go.sum
  └── main.go
          

Main module



  package main

  import "github.com/pito-svk/grafana-simple-dashboard-generator/cmd"

  func main() {
    cmd.Execute()
  }
          

Main module initializes a CLI application which is defined in cmd/root.go


cmd/root.go



  package cmd

  import (
    "github.com/spf13/cobra"
  )

  var rootCmd = &cobra.Command{
    Use:   "grafana-simple-dashboard-generator",
    Short: "Grafana simple dashboard generator",
  }

  func Execute() {
    cobra.CheckErr(rootCmd.Execute())
  }
          

cmd/root.go file contains variable rootCmd calling cobra.Command, which initializes cobra CLI with Use and Short properties.

Use property is a command name. In this case, you will call: grafana-simple-dashboard-generator [args].

Short property is a short description of the command and is shown when you call help command: grafana-simple-dashboard-generator help:


  Grafana simple dashboard generator

  Usage:
    grafana-simple-dashboard-generator [command]

  Available Commands:
    help        Help about any command
    init        Generate new grafana dashboard

  Flags:
    -h, --help   help for grafana-simple-dashboard-generator

  Use "grafana-simple-dashboard-generator [command] --help" for more information about a command.


cmd/init.go


            
  package cmd

  import (
    "encoding/json"
    "fmt"
    "os"

    "github.com/pito-svk/grafana-simple-dashboard-generator/dashboard"
    "github.com/spf13/cobra"
  )

  var (
    mode     string
    output   string
    filepath string
    title    string
  )

  var initCmd = &cobra.Command{
    Use:   "init",
    Short: "Generate new grafana dashboard",
    RunE: func(cmd *cobra.Command, args []string) error {
      if output != "console" && output != "file" {
        return fmt.Errorf("invalid value for output. Allowed values: [\"console\", \"file\"]")
      }

      if mode != "basic" {
        return fmt.Errorf("invalid value for mode. Allowed values: [\"default\"]")
      }

      if output == "file" && filepath == "" {
        return fmt.Errorf("filepath is required when output is \"file\"")
      }

      dashboardParams := dashboard.GrafanaDashboardParams{Title: title}

      dashboard := dashboard.GenerateDashboard(&dashboardParams)
      jsonRes, _ := json.MarshalIndent(dashboard, "", "	")

      if output == "console" {
        fmt.Println(string(jsonRes))
      } else if output == "file" {
        os.WriteFile(filepath, jsonRes, 0644)
      }

      return nil
    },
  }

  func init() {
    rootCmd.AddCommand(initCmd)

    initCmd.Flags().StringVarP(&mode, "mode", "m", "default", "dashboard mode")
    initCmd.Flags().StringVarP(&output, "output", "o", "console", "specify output mode")
    initCmd.Flags().StringVarP(&filepath, "filepath", "f", "", "specify a filepath to generate dashboards")
    initCmd.Flags().StringVarP(&title, "title", "t", "Server monitoring", "specify a title for dashboard")
  }
      

cmd/init.go contains logic for init command which is responsible for generating Grafana dashboard.

In init function, there are four flags available so far: mode, output, filepath, and title.

Mode will specify what you want to see in the Grafana dashboard, such as CPU, memory, etc. Currently only default mode is allowed, which will contain all needed metrics in the dashboard.

Output specifies how you want your dashboard to receive. Either in console output in terminal or in specific file.

Filepath is required when file output is specified. It specifies a path where to write the Grafana dashboard.

Title is the title of the Grafana dashboard.

The core logic of init command lies in RunE handler, which also handles a validation.

Inside of this handler, there is "dashboard.GenerateDashboard(&dashboardParams)" responsible for generating the Grafana dashboard object.


Conclusion


So far I was presenting the skeleton of Grafana simple dashboard generator project. In the next article, I will work on the actual logic of generating Grafana dashboard.