Using Grafana JSON Model — HowTo
Maybe it is just me but every couple of weeks I would find myself wanting to edit a large Grafana dashboard. Usually it would involve something like copying 10 panels (graphs) from one dashboard to another. Or copying them on the same dashboard but with some parameter modified.
While repeated rows provide a simple way to create the same set of graphs for different variables, they are not very flexible. For example, we cannot set an alert on some metric for each of the repeated rows. If we set an alert, it would fire multiple times for the panels in the first row itself.
Alternatively, we can create each panel again. But doing this will be painfully slow and prone to errors. Here I’ll walk through an example JSON which I’ll modify to copy a bunch of graphs to make a fully functional Grafana dashboard.
So let’s start.
The dashboard I’ll create will have a bunch of metrics like p50, p90, p99 response times, Healthy host count, Unhealthy host count, Active connections, Active requests and so on. These metrics need to be plotted for multiple clusters.
The abstract hierarchy of the final dashboard would be something like this:
- cluster1
- p50 panel
- p90 panel
- p99 panel
- … - cluster2
- p50 panel
- … - cluster3
- p50 panel
- … - …
We start with creating all the panels for cluster1. This step has to be done manually. Although even here if few panels have almost the same query, alerts, etc, you can create one panel and then use theCopy
option of the panel to create copies and then edit parts of them.
Your dashboard would look something like Fig 1 at this point.
Collapse the Cluster1
row. Save the dashboard.
Now comes the fun part. Go to Settings of the dashboard and click on JSON Model.
Copy the JSON to any editor of your choice. I prefer Sublime Text.
Now let’s say all the queries of cluster2
can be formed from cluster1
queries by just doing a simple replace. This is usually the case with related clusters. For example, two different services will have a label on their timeseries like service_name
. We are basically replacing the value for this label.
Steps to copy:
- Find the JSON configuration for
Cluster1
. It should look something like this:
{
"collapsed": true,
"datasource": null,
"gridPos": {
"h": 1,
"w": 24,
"x": 0,
"y": 16
},
"id": 18,
"panels": [...]
"title": "Cluster1",
"type": "row"
},
The panels array would contain the graphs we want to copy. Each panel looks something like this (irrelevant key-values hidden).
{
...
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 17
},
"id": 59,
...
}
Copy the whole config for Cluster1
to a separate file.
- Find the maximum
id
of all the panels that are currently present in the original JSON config. We will giveid
s starting frommaxid+1
to all the panels forCluster2
. Replaceid
s for the panels in the copied config 1-by-1. - Then we need to update the gridPos values. If this is not done correctly, the panels in the resulting dashboard will be all over the place. To do this, find the max
y
value inCluster1
. Adding theh
(height) in thegridPos
of the panel with maxy
value plus 1 will be the startingy
coordinates forCluster2
(let’s call thisy2
). Also find they
value for the rowCluster1
(let’s call ity1
). Replace they
values in the copiedCluster1
config withy+y2-y1
. - Do a Find and Replace of
cluster1
withcluster2
to fix the queries. - Append this config after the config for
Cluster1
in the original config. - Increase the
version
value near the end of the config. - Copy the config back to JSON model on the dashboard and press Save.
And that’s it! Your dashboard should look something like Fig 2.
To create more copies of the cluster just follow the same steps as above.
Tip: Sometimes you may mess up the JSON format. Run a JSON validator before pasting the config.