Skip to content

Commit 8e9f242

Browse files
committed
chore: update grafana dashboards and add backup instructions
Resolves #3 by removing severity filters from Grafana dashboards. Changes made: - Added backing up instructions under `docs/DASHBOARD_EXPORT_GUIDE.md` - Updated submodules to latest version. - Updated dashboards in provisioning to align with production state. - Adapted Grafana version in Dockerfile for consistent local testing. - Use aliased index in datasource provisioning (see SRGSSR/pillarbox-monitoring-transfer#16)
1 parent 1b231dd commit 8e9f242

File tree

12 files changed

+539
-150
lines changed

12 files changed

+539
-150
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,11 @@ git config core.hooksPath .githooks/
166166
167167
Refer to our [Contribution Guide](docs/CONTRIBUTING.md) for more detailed information.
168168
169+
### Exporting Dashboards from production
170+
171+
See the [Grafana Dashboard Export Guide](./docs/DASHBOARD_EXPORT_GUIDE.md) for information on how
172+
to export and backup the dashboards in production.
173+
169174
## License
170175
171176
This project is licensed under the [MIT License](LICENSE).

docs/DASHBOARD_EXPORT_GUIDE.md

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# Grafana Dashboard Export Guide
2+
3+
This guide provides a method to export all dashboards within a specified folder in Grafana into a
4+
single zip file, containing individual JSON files for each dashboard.
5+
6+
## Steps
7+
8+
### 1. Open the Browser Console
9+
10+
- Open your Grafana instance and log in if prompted by SSO.
11+
- Press **F12** (or right-click and select **Inspect**) to open Developer Tools.
12+
- Navigate to the **Console** tab.
13+
14+
### 2. Load JSZip Library
15+
16+
- To manage multiple files in a zip, we’ll use the [JSZip library](https://stuk.github.io/jszip/).
17+
Copy and paste the following code into the console and press **Enter**:
18+
19+
```javascript
20+
var script = document.createElement('script');
21+
script.src = 'https://cdnjs.cloudflare.com/ajax/libs/jszip/3.7.1/jszip.min.js';
22+
document.head.appendChild(script);
23+
```
24+
25+
- Verify that JSZip is loaded by typing `JSZip` into the console and pressing **Enter**. You should
26+
see an object or function returned.
27+
28+
### 3. Run the Export Script
29+
30+
- Copy and paste the following code into the console and press **Enter**:
31+
32+
```javascript
33+
async function exportAllDashboardsWithFolders() {
34+
const zip = new JSZip();
35+
36+
// Step 1: Get all folders
37+
const folderResponse = await fetch(`/api/folders`);
38+
const folders = await folderResponse.json();
39+
const folderMap = {};
40+
folders.forEach(folder => {
41+
folderMap[folder.uid] = folder.title.replace(/[/\\?%*:|"<>]/g, ''); // Clean up folder names
42+
});
43+
44+
// Step 2: Fetch all dashboards across folders
45+
const response = await fetch(`/api/search?type=dash-db`);
46+
const dashboards = await response.json();
47+
48+
for (const dashboard of dashboards) {
49+
const uid = dashboard.uid;
50+
const title = dashboard.title.replace(/[/\\?%*:|"<>]/g, ''); // Clean up filename
51+
const folderName = folderMap[dashboard.folderUid] || 'General';
52+
53+
// Fetch each dashboard's JSON
54+
const dashboardResponse = await fetch(`/api/dashboards/uid/${uid}`);
55+
const dashboardData = await dashboardResponse.json();
56+
57+
// Add each dashboard JSON to the zip, organized by folder
58+
zip.file(`${folderName}/${title}.json`, JSON.stringify(dashboardData.dashboard, null, 2));
59+
console.log(`Added to zip: ${folderName}/${title}`);
60+
}
61+
62+
// Step 3: Generate the zip and trigger download
63+
zip.generateAsync({ type: 'blob' }).then(function (content) {
64+
const link = document.createElement('a');
65+
link.href = URL.createObjectURL(content);
66+
link.download = 'grafana_dashboards.zip';
67+
document.body.appendChild(link);
68+
link.click();
69+
document.body.removeChild(link);
70+
console.log("Downloaded all dashboards as zip with folder structure.");
71+
});
72+
}
73+
74+
exportAllDashboardsWithFolders();
75+
```
76+
- The script will create a zip containing individual JSON files for each dashboard and will follow
77+
Grafana folder structure.
78+
- Each JSON file is named after the dashboard title and represents a backup of the dashboard’s
79+
configuration.

pillarbox-monitoring-grafana/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Dockerfile for grafana
2-
FROM grafana/grafana:11.0.0
2+
FROM grafana/grafana:10.4.1
33

44
# Copy provisioning and dashboards
55
COPY ./provisioning /etc/grafana/provisioning

pillarbox-monitoring-grafana/dashboards/device_breakdown.json renamed to pillarbox-monitoring-grafana/dashboards/Device Breakdown.json

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,13 @@
1818
"editable": true,
1919
"fiscalYearStartMonth": 0,
2020
"graphTooltip": 0,
21+
"id": 3,
2122
"links": [],
2223
"panels": [
2324
{
2425
"datasource": {
2526
"type": "grafana-opensearch-datasource",
26-
"uid": "de0gi09a14ow0e"
27+
"uid": "PB728120E9B299770"
2728
},
2829
"description": "Usage by Operating System for the selected time range.",
2930
"fieldConfig": {
@@ -283,15 +284,15 @@
283284
],
284285
"datasource": {
285286
"type": "opensearch",
286-
"uid": "de0gi09a14ow0e"
287+
"uid": "PB728120E9B299770"
287288
},
288289
"metrics": [
289290
{
290291
"id": "1",
291292
"type": "count"
292293
}
293294
],
294-
"query": "event_name:START AND data.player.platform:${platform} AND\ndata.media.id:${bu:raw}",
295+
"query": "event_name:START \nAND data.player.platform:${platform}\nAND data.media.id:${bu:raw}",
295296
"refId": "A",
296297
"timeField": "@timestamp"
297298
}
@@ -302,7 +303,7 @@
302303
{
303304
"datasource": {
304305
"type": "grafana-opensearch-datasource",
305-
"uid": "de0gi09a14ow0e"
306+
"uid": "PB728120E9B299770"
306307
},
307308
"description": "Usage by device type for the selected time range.",
308309
"fieldConfig": {
@@ -562,15 +563,15 @@
562563
],
563564
"datasource": {
564565
"type": "opensearch",
565-
"uid": "de0gi09a14ow0e"
566+
"uid": "PB728120E9B299770"
566567
},
567568
"metrics": [
568569
{
569570
"id": "1",
570571
"type": "count"
571572
}
572573
],
573-
"query": "event_name:START AND data.player.platform:${platform} AND\ndata.media.id:${bu:raw}",
574+
"query": "event_name:START\nAND data.player.platform:${platform}\nAND data.media.id:${bu:raw}",
574575
"refId": "A",
575576
"timeField": "@timestamp"
576577
}
@@ -581,7 +582,7 @@
581582
{
582583
"datasource": {
583584
"type": "grafana-opensearch-datasource",
584-
"uid": "de0gi09a14ow0e"
585+
"uid": "PB728120E9B299770"
585586
},
586587
"description": "Usage by browser for the selected time range.",
587588
"fieldConfig": {
@@ -736,15 +737,15 @@
736737
],
737738
"datasource": {
738739
"type": "opensearch",
739-
"uid": "de0gi09a14ow0e"
740+
"uid": "PB728120E9B299770"
740741
},
741742
"metrics": [
742743
{
743744
"id": "1",
744745
"type": "count"
745746
}
746747
],
747-
"query": "event_name:START AND data.player.platform:${platform} AND\ndata.media.id:${bu:raw}",
748+
"query": "event_name:START\nAND data.player.platform:${platform}\nAND data.media.id:${bu:raw}",
748749
"refId": "A",
749750
"timeField": "@timestamp"
750751
}
@@ -755,7 +756,7 @@
755756
{
756757
"datasource": {
757758
"type": "grafana-opensearch-datasource",
758-
"uid": "de0gi09a14ow0e"
759+
"uid": "PB728120E9B299770"
759760
},
760761
"description": "The top 10 operating systems' versions for the selected time range.",
761762
"fieldConfig": {
@@ -856,15 +857,15 @@
856857
],
857858
"datasource": {
858859
"type": "opensearch",
859-
"uid": "de0gi09a14ow0e"
860+
"uid": "PB728120E9B299770"
860861
},
861862
"metrics": [
862863
{
863864
"id": "1",
864865
"type": "count"
865866
}
866867
],
867-
"query": "event_name:START AND data.player.platform:${platform} AND\ndata.media.id:${bu:raw}",
868+
"query": "event_name:START\nAND data.player.platform:${platform}\nAND data.media.id:${bu:raw}",
868869
"refId": "A",
869870
"timeField": "@timestamp"
870871
}
@@ -938,7 +939,7 @@
938939
{
939940
"datasource": {
940941
"type": "grafana-opensearch-datasource",
941-
"uid": "de0gi09a14ow0e"
942+
"uid": "PB728120E9B299770"
942943
},
943944
"description": "The top 10 device models for the selected time range.",
944945
"fieldConfig": {
@@ -1033,15 +1034,15 @@
10331034
],
10341035
"datasource": {
10351036
"type": "opensearch",
1036-
"uid": "de0gi09a14ow0e"
1037+
"uid": "PB728120E9B299770"
10371038
},
10381039
"metrics": [
10391040
{
10401041
"id": "1",
10411042
"type": "count"
10421043
}
10431044
],
1044-
"query": "event_name:START AND data.player.platform:${platform} AND\ndata.media.id:${bu:raw}",
1045+
"query": "event_name:START\nAND data.player.platform:${platform}\nAND data.media.id:${bu:raw}",
10451046
"refId": "A",
10461047
"timeField": "@timestamp"
10471048
}
@@ -1052,7 +1053,7 @@
10521053
{
10531054
"datasource": {
10541055
"type": "grafana-opensearch-datasource",
1055-
"uid": "de0gi09a14ow0e"
1056+
"uid": "PB728120E9B299770"
10561057
},
10571058
"description": "The top 10 browsers' versions for the selected time range.",
10581059
"fieldConfig": {
@@ -1153,15 +1154,15 @@
11531154
],
11541155
"datasource": {
11551156
"type": "opensearch",
1156-
"uid": "de0gi09a14ow0e"
1157+
"uid": "PB728120E9B299770"
11571158
},
11581159
"metrics": [
11591160
{
11601161
"id": "1",
11611162
"type": "count"
11621163
}
11631164
],
1164-
"query": "event_name:START AND data.player.platform:${platform} AND\ndata.media.id:${bu:raw}",
1165+
"query": "event_name:START\nAND data.player.platform:${platform}\nAND data.media.id:${bu:raw}",
11651166
"refId": "A",
11661167
"timeField": "@timestamp"
11671168
}
@@ -1239,14 +1240,15 @@
12391240
"templating": {
12401241
"list": [
12411242
{
1243+
"allValue": "*",
12421244
"current": {
12431245
"selected": false,
12441246
"text": "All",
12451247
"value": "$__all"
12461248
},
12471249
"datasource": {
12481250
"type": "opensearch",
1249-
"uid": "de0gi09a14ow0e"
1251+
"uid": "PB728120E9B299770"
12501252
},
12511253
"definition": "{\n \"find\": \"terms\",\n \"field\": \"data.player.platform.keyword\",\n \"size\": 1000\n}",
12521254
"description": "Filter by player platform.",
@@ -1257,7 +1259,7 @@
12571259
"name": "platform",
12581260
"options": [],
12591261
"query": "{\n \"find\": \"terms\",\n \"field\": \"data.player.platform.keyword\",\n \"size\": 1000\n}",
1260-
"refresh": 1,
1262+
"refresh": 2,
12611263
"regex": "",
12621264
"skipUrlSync": false,
12631265
"sort": 1,
@@ -1318,11 +1320,10 @@
13181320
"from": "now-1h",
13191321
"to": "now"
13201322
},
1321-
"timeRangeUpdatedDuringEditOrView": false,
13221323
"timepicker": {},
13231324
"timezone": "browser",
13241325
"title": "Device Breakdown",
13251326
"uid": "cdrj6qnc10veoe",
1326-
"version": 1,
1327+
"version": 6,
13271328
"weekStart": ""
13281329
}

0 commit comments

Comments
 (0)