Dashboards aus JSON-Dateien provisionieren
Lade Dashboards von der Platte, bilde Ordner aus Verzeichnissen ab und erstelle sie, ohne Änderungen zu verlieren.
Dashboards sind JSON-Dokumente, die sich leicht in Git ablegen lassen. Ein Dashboard-Provider sagt Grafana, welchen Ordner es beobachten soll, und Grafana lädt jede dort gefundene JSON-Datei und prüft danach weiter auf Änderungen. Diese Anleitung behandelt die Provider-Datei, die Ordnerzuordnung, das Dashboard-JSON selbst und einen Workflow, um Dashboards zu erstellen, ohne bei reinen UI-Bearbeitungen zu landen.
Die Provider-Datei
provisioning/dashboards/providers.yaml:
apiVersion: 1
providers:
- name: default
orgId: 1
type: file
disableDeletion: false
updateIntervalSeconds: 30
allowUiUpdates: false
options:
path: /var/lib/grafana/dashboards
foldersFromFilesStructure: true
Was jedes Feld tut:
nameist erforderlich und muss über alle Provider eindeutig sein.options.pathist das Verzeichnis, das Grafana nach JSON-Dateien scannt. Es muss im Container existieren.updateIntervalSecondsgibt an, wie oft Grafana den Pfad neu scannt. Alle Dashboards werden beim Start geladen, und Änderungen werden danach ohne Neustart aufgegriffen.allowUiUpdates: Beifalsekann ein provisioniertes Dashboard nicht aus der UI gespeichert werden, was Git maßgeblich hält. Beitruebleiben UI-Speicherungen in der Datenbank erhalten, bis sich die Quelldatei ändert, woraufhin die Datei sie überschreibt.disableDeletion: Beitrueentfernt das Löschen einer Datei das Dashboard nicht aus Grafana. Lass es auffalse, wenn Git die Wahrheit sein soll.folderoderfolderUidlegen alle Dashboards in einen benannten Ordner. Ohne sie landen Dashboards im Stammverzeichnis.foldersFromFilesStructure: truebildet Unterverzeichnisse vonpathauf Grafana-Ordner ab. LassfolderundfolderUidleer, wenn du es nutzt. Verschachtelte Ordner werden nicht unterstützt, eine Ebene Unterverzeichnis ist also das Limit.
Das Repository nach Ordnern organisieren
Mit foldersFromFilesStructure: true erzeugt dieses Layout:
dashboards/
├── infrastructure/
│ ├── node-exporter.json
│ └── kubernetes.json
└── applications/
└── webapp.json
zwei Grafana-Ordner, infrastructure und applications, mit den Dashboards darin. Nutze stattdessen separate Provider, wenn du pro Gruppe unterschiedliche Einstellungen brauchst, etwa einen Provider mit allowUiUpdates: true für einen „Scratch“-Bereich.
Grundlagen des Dashboard-JSON
Eine provisionierte Datei muss das Dashboard-Modell selbst enthalten, mit uid und title auf oberster Ebene. Verpacke es nicht in den Umschlag {"dashboard": {...}, "overwrite": true}, den die HTTP-API nutzt, was eine häufige Ursache für den Fehler „Dashboard title cannot be empty“ ist.
{
"uid": "webapp-overview",
"title": "Webapp Overview",
"tags": ["webapp", "provisioned"],
"schemaVersion": 39,
"version": 1,
"refresh": "30s",
"time": { "from": "now-6h", "to": "now" },
"templating": {
"list": [
{
"name": "namespace",
"type": "query",
"datasource": { "type": "prometheus", "uid": "prometheus" },
"query": "label_values(kube_pod_info, namespace)"
}
]
},
"panels": [
{
"id": 1,
"type": "timeseries",
"title": "Request rate",
"gridPos": { "h": 8, "w": 12, "x": 0, "y": 0 },
"datasource": { "type": "prometheus", "uid": "prometheus" },
"targets": [
{
"refId": "A",
"expr": "sum(rate(http_requests_total{namespace=\"$namespace\"}[5m]))",
"datasource": { "type": "prometheus", "uid": "prometheus" }
}
]
}
]
}
Richtlinien für Dashboards, die sich als Code gut verhalten:
- Setze eine stabile
uid. Grafana aktualisiert bei jedem Laden das Dashboard mit dieser UID. Vermeide es, eine UID über Dateien hinweg wiederzuverwenden oder denselben Titel zweimal in einem Ordner zu haben. - Lass die numerische
idweg. Sie wird von der Datenbank vergeben und unterscheidet sich zwischen Instanzen. - Referenziere Datenquellen per UID, passend zur
uid, die du provisioniert hast ({"type": "prometheus", "uid": "prometheus"}). Zum Teilen exportierte Dashboards können Platzhalter wie${DS_PROMETHEUS}enthalten, die du durch die echte UID oder eine Template-Variable für Datenquellen ersetzen musst. - Interpolation von Umgebungsvariablen funktioniert innerhalb von Dashboard-JSON nicht. Nutze Dashboard-Template-Variablen für Unterschiede pro Umgebung.
- Grafana 13 speichert Dashboards intern in einem neueren Schema und migriert älteres JSON beim Laden, bestehende Dateien funktionieren also weiter.
In der UI erstellen, dann das Ergebnis zurück nach Git bringen
Panel-JSON von Hand zu schreiben ist langsam, daher entwerfen die meisten Teams in der UI und exportieren. Ein Workflow, der Dateien als Wahrheit hält:
- Betreibe eine Scratch-Instanz (das Compose-Setup aus der früheren Anleitung), in der ein Provider
allowUiUpdates: truehat. - Baue oder verfeinere das Dashboard in der UI.
- Exportiere es als JSON aus dem Teilen- oder Export-Menü des Dashboards. Wähle die Option, die zum externen Teilen exportiert, wenn Datenquellen durch Eingaben ersetzt werden sollen, und setze dann die echten UIDs.
- Entferne die numerische
id, setze eine stabileuidund committe die Datei in den Repository-Ordner. - Öffne einen Pull Request. Das Produktions-Grafana greift sie nach dem Merge auf, und
allowUiUpdates: falseverhindert dort, dass jemand abweicht.
Du kannst ein bestehendes Dashboard auch über die API abrufen:
curl -s -u admin:$GRAFANA_ADMIN_PASSWORD \
http://localhost:3000/api/dashboards/uid/webapp-overview \
| jq '.dashboard | del(.id)' > dashboards/applications/webapp.json
Formatiere das JSON einheitlich (zum Beispiel jq -S .), damit Diffs echte Änderungen zeigen.
Dashboards aus Code erzeugen
Wenn viele Dashboards eine Form teilen, erzeuge das JSON, statt es zu kopieren. Das Grafana Foundation SDK (Go, TypeScript, Python, PHP, Java) baut Dashboards aus typisiertem Code, und seine Ausgabe ist dasselbe JSON, das du in den Provider-Ordner legst. Die Anleitung zum Foundation SDK in dieser Reihe behandelt es.
In CI validieren
Fange Fehler ab, bevor sie Grafana erreichen:
# gültiges JSON?
jq empty dashboards/**/*.json
# hat jede Datei eine uid und einen title?
for f in dashboards/*/*.json; do
jq -e '.uid and .title' "$f" >/dev/null || echo "missing uid/title: $f"
done
# doppelte uids?
jq -r '.uid' dashboards/*/*.json | sort | uniq -d
Anwenden und prüfen
Änderungen werden innerhalb von updateIntervalSeconds aufgegriffen. Um einen Rescan zu erzwingen:
curl -X POST -u admin:$GRAFANA_ADMIN_PASSWORD \
http://localhost:3000/api/admin/provisioning/dashboards/reload
curl -s -u admin:$GRAFANA_ADMIN_PASSWORD \
"http://localhost:3000/api/search?type=dash-db" | jq '.[] | {title, uid, folderTitle}'
Erscheint ein Dashboard nicht, prüfe die Logzeilen von Start und Rescan aus dem Provisioning-Logger. Die üblichen Ursachen sind ein Pfad, der im Container nicht existiert, JSON im API-Umschlag oder zwei Dateien mit derselben uid.
Beliebte Anleitungen
-
Grafana als Code betreiben: Das große Ganze Was in Dateien leben kann, was eine API braucht und wie die Teile zusammenpassen. -
Den Grafana-Server mit grafana.ini und Umgebungsvariablen konfigurieren Wisse, wo Konfigurationsdateien liegen, wie Überschreibungen geordnet sind und wie du Einstellungen in Git hältst. -
Alert-Regeln, Contact Points und Notification Policies provisionieren Definiere die gesamte Alerting-Pipeline in YAML, damit sie wie Code geprüft und versioniert wird. -
Grafana auf Kubernetes mit Helm und Provisioning-Values deployen Betreibe Grafana aus einem Helm-Chart, bei dem Datenquellen, Dashboards und Einstellungen alle aus Values-Dateien stammen. -
Provisioning von der Kommandozeile neu laden, prüfen und Fehler beheben Finde heraus, was Grafana geladen hat, lade ohne Neustart neu und behebe die üblichen Provisioning-Fehler.