Datenvisualisierung mit Grafana
Nachdem wir die Datenerfassung mit Prometheus bewerkstelligt haben, ist es nun natürlich sinnvoll auch eine Datenvisualisierung einzurichten. Hier kommt Grafana1 ins Spiel.
Leider ist Grafana nicht in den offiziellen Debian Quellen enthalten. Es gibt aber ein Repo2, welches von den Machern von Grafana selbst bereitgestellt wird.
Mit den folgenden Befehlen fügen wir das Repo unseren Paketquellen hinzu und starten die Grafana-Installation:
apt-get install -y apt-transport-https software-properties-common wget
wget -q -O /usr/share/keyrings/grafana.key https://apt.grafana.com/gpg.key
echo "deb [signed-by=/usr/share/keyrings/grafana.key] https://apt.grafana.com stable main" | tee -a /etc/apt/sources.list.d/grafana.list
apt update
apt install grafana
systemctl restart grafana
Alternativ kann Grafana als Docker-Container verwendet werden:
version: "3.8"
services:
grafana:
image: grafana/grafana:latest
container_name: grafana
restart: unless-stopped
environment:
- TERM=linux
- GF_INSTALL_PLUGINS=grafana-clock-panel,grafana-polystat-panel
ports:
- '3000:3000'
volumes:
- 'grafana_storage:/var/lib/grafana'
volumes:
grafana_storage: {}
Standardmäßig startet Grafana auf dem Port 3000
. Rufen wir die Weboberfläche im Browser auf, begrüßt uns Grafana mit einer Loginmaske. Der Standarduser ist admin
und das Kennwort lautet ebenfalls admin
.
Unter Home > Connections > Your Connections > Data Sources
bzw. bei älteren Grafana-Versionen unter Administration > Data Sources
(ja, gewöhnt euch schonmal dran, dass bei Grafana mit neueren Versionen die Dinge nicht immer leichter Auffindbar sind) können wir über den Button Add new data source
eine Verbindung zu unserer Prometheus-Instanz herstellen.
Im Grunde reicht es das Feld URL
noch einmal händisch mit dem Wert zu befüllen, den Grafana bereits als Beispiel anzeigt http://localhost:9090
.
Ist das Feld ausgefüllt, können wir die Einstellungen über den Button Save & Test
sichern.
Anschließend sollte unsere Datenquelle zur Verfügung stehen:
Nun können wir damit beginnen unser erstes Dashboard zu erstellen. Falls du noch keinen ESP8266 mit Temperatursensor gebastelt hast, oder diesen noch nicht via MQTT seine Daten an Prometheus senden lässt, kannst du einfach folgende Quelle in /etc/prometheus/prometheus.yml
einfügen:
- job_name: 'wttrin'
scheme: https
static_configs:
- targets: ['wttr.in']
metrics_path: '/cgn'
params:
format: ['p1']
Nach einem Neustart von Prometheus ruft dieser Daten vom Dienst wttr.in
ab. In obigen Beispiel werden die Daten von Köln (metrics_path: '/cgn'
) abgefragt. Der Parameter format: ['p1']
weißt wttr.in
an die Daten im Format eines Prometheus-Exporters auszugeben. Der Dienst ist leider mitunter etwas unzuverlässig, da er manchmal das API-Request-Limit des genutzten Wetterdienst überschreitet. Also nicht verzweifeln, wenn es mal nicht klappen sollte. Welche Daten wttr.in
liefert, kann man sich einfach durch den Aufruf von https://wttr.in/cgn?format=p1
ansehen.
Da wir nun eine sinnvolle Datenquelle haben, können wir uns nun wirklich an unser erstes Dashboard machen. Dazu rufen wir http://localhost:3000/dashboards
auf und klicken auf den Button New > Dashboard
und dort auf Add Visualization
.
Die Erstellung von Dashboards kann recht komplex werden. Aber der wesentliche Prozess bleibt immer gleich und relativ einfach. Über den Button Add > Visualisation
legt man einen Graphen an (dies haben wir bei einem komplett leeren Dashboard über den Klick auf Add Visualization
bereits vorgenommen).
Standardmäßig wählt Grafana hierbei automatisch den Datentypen Time series
. Über ein Drop Down Menü oben rechts, in dem nun Time series
ausgewählt ist, kann der Datentyp bei Bedarf geändert werden.
In das Feld Metrics Browser
unterhalb des Bereichs für den Graphen können wir nun PromQL
Abfragen eingeben. Hier reicht es für einfache Abfragen aus, einfach den Namen eines Datensatzes einzugeben, diese erhalten wir in der Ausgabe von https://wttr.in/cgn?format=p1 also z.B. temperature_celsius
.
In der rechten Spalte können wir nun noch zahlreiche Einstellungen vornehmen, z.B. können wir unter Standard options > Unit
den Wert Temperature / Celsius (°C)
auswählen.
Wenn wir mit unseren Einstellungen zufrieden sind, können wir die Grapherstellung mit einem Klick auf den Button Apply
oben rechts abschließen.
Ich fand es besonders hilfreich mir bereits fertige Dashboards herunterzuladen3. Wichtig ist hierbei darauf zu achten, dass diese Prometheus als Data Source nutzen und man den passenden Prometheus-Exporter nutzt bzw. diesen einrichtet. Alternativ oder ergänzend sollte man sich die Einträge 4 und 5 in der Grafana-Dokumentation anschauen.
Für wttr.in habe ich ein kleines Beispieldashboard bereitgestellt6. Um es zu Importieren kann man in Grafana die Option Import dashboard
nutzen, am einfachsten erreicht man diese unter der URL http://localhost:3000/dashboard/import
.
Es kann zunächst ziemlich erschlagend sein, sich mit den weiteren Möglichkeiten der Visualisierung zu befassen und Grafana versteckt einige Funktionen auch regelrecht (es sind aber natürlich auch sehr viele). Es lohnt sich jedoch sehr, sich damit eingehender zu beschäftigen. Grafana kann zu einer regelrechten Monitoring- und Infozentrale ausgebaut werden und eignet sich auch zur Serverüberwachung. Hier kann insbesondere der zeitliche Verlauf oft sehr erhellend sein. Ich habe so schon so manches Performanceproblem identifizieren können.
Wer Grafana gerne hinter einem Nginx Reverse Proxy betreiben möchte, kann folgende Konfiguration nutzen:
server {
listen 80;
listen [::]:80;
listen 443 ssl;
listen [::]:443;
server_name grafana.example.org;
ssl_certificate /var/lib/dehydrated/certs/grafana.example.org/fullchain.pem;
ssl_certificate_key /var/lib/dehydrated/certs/grafana.example.org/privkey.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m; # about 40000 sessions
ssl_session_tickets off;
ssl_dhparam /etc/ssl/dhparams.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
gzip off;
add_header Strict-Transport-Security "max-age=63072000" always;
ssl_trusted_certificate /var/lib/dehydrated/certs/grafana.example.org/fullchain.pem;
ssl_stapling on;
ssl_stapling_verify on;
resolver 127.0.0.1;
# for letsencrypt
location /.well-known/acme-challenge/ {
root /var/www/html/;
try_files $uri $uri/ =404;
}
location / {
if ($ssl_protocol = "") {
rewrite ^ https://$server_name$request_uri? permanent;
}
proxy_pass http://localhost:3000/;
proxy_set_header Host $http_host;
client_max_body_size 8192M;
proxy_redirect off;
proxy_intercept_errors off;
proxy_read_timeout 86400s;
proxy_ignore_client_abort on;
proxy_connect_timeout 120s;
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
proxy_headers_hash_max_size 512;
proxy_buffering on;
proxy_cache_bypass $http_pragma $http_authorization $cookie_nocache;
}
location /api/live/ {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $http_host;
proxy_pass http://localhost:3000;
}
}