Aufgabe 09 - InfluxDB mit Grafana
Aufgabe 09 - InfluxDB mit Grafana
Abschnitt betitelt „Aufgabe 09 - InfluxDB mit Grafana“InfluxDB und Grafana sollen ausprobiert und damit etwas kennengelernt werden. Die Übung umfasst:
- Testdaten mit Mockaroo erzeugen (CSV)
- InfluxDB (OSS 2.x) per Docker Compose starten und initial konfigurieren
- CSV-Daten in InfluxDB importieren (CLI)
- Daten in Grafana als Dashboard visualisieren (Flux / InfluxDB 2.x)
1) Voraussetzungen
Abschnitt betitelt „1) Voraussetzungen“- Docker + Docker Compose installiert
- Browserzugang zu https://mockaroo.com/
- Optional:
influxCLI lokal installiert oder Import über einen CLI-Container
Anmerkung: InfluxDB wird beim Start per Docker Compose automatisch vorkonfiguriert, statt manuell im Web-Setup.
2) Datenset in Mockaroo generieren
Abschnitt betitelt „2) Datenset in Mockaroo generieren“Erstelle auf Mockaroo ein Schema mit z. B. 10.000 Zeilen und exportiere dieses als CSV.
Spalten (Beispiel “Smart Building Sensoren”)
_measurement→ Formula → Gib"sensors"ein (konstanter Wert für alle Zeilen)time→ Datetime (Format ISO 8601, z. B.2026-01-20T12:34:56Z)building→ Custom List (z. B.E101,E102,LAB1,LAB2)device→ Custom List (z. B.device1,device2,device3,device4)temperature_c→ Number (z. B. 18–28, decimals 1)humidity_rh→ Number (z. B. 25–65, decimals 1)co2_ppm→ Number (z. B. 400–2000, decimals 0)power_w→ Number (z. B. 0–2500, decimals 0)
Hinweis (wichtig):
- Mockaroo kann in der kostenlosen Version pro Export maximal 1.000 Zeilen exportieren.
_measurementist Pflicht für InfluxDB - verwende den Typ Formula mit dem Wert"sensors"timewird später als Timestamp verwendet.building,deviceeignen sich als Tags (Filter/Gruppierung).- Messwerte (
temperature_c, …) sind Fields. - Reihenfolge beachten:
_measurement,time,building,device,temperature_c,humidity_rh,co2_ppm,power_w
3) Service Stack aufbauen: InfluxDB + Grafana
Abschnitt betitelt „3) Service Stack aufbauen: InfluxDB + Grafana“3.1 Ordnerstruktur
Abschnitt betitelt „3.1 Ordnerstruktur“Lege einen Projekt-Ordner an, z. B. influx-grafana-lab/ und darin diese Struktur:
influx-grafana-lab/ docker-compose.yml grafana/ provisioning/ datasources/ datasource.yml data/ (optional, falls CSV hier liegt)3.2 Docker Compose
Abschnitt betitelt „3.2 Docker Compose“Stelle dieses docker-compose.yml ins Projekt:
services: influxdb: image: influxdb:2 container_name: influxdb ports: - "8086:8086" volumes: - influxdb_data:/var/lib/influxdb2 - influxdb_config:/etc/influxdb2 environment: - DOCKER_INFLUXDB_INIT_MODE=setup - DOCKER_INFLUXDB_INIT_USERNAME=admin - DOCKER_INFLUXDB_INIT_PASSWORD=adminadminadmin - DOCKER_INFLUXDB_INIT_ORG=school - DOCKER_INFLUXDB_INIT_BUCKET=sensors - DOCKER_INFLUXDB_INIT_RETENTION=0 # keine Vorhaltezeit, alle Daten behalten - DOCKER_INFLUXDB_INIT_ADMIN_TOKEN=school-super-token
grafana: image: grafana/grafana:latest container_name: grafana ports: - "3000:3000" # Falls Port 3000 belegt ist, z.B.: "4000:3000" depends_on: - influxdb volumes: - grafana_data:/var/lib/grafana - ./grafana/provisioning:/etc/grafana/provisioning
volumes: influxdb_data: influxdb_config: grafana_data:3.3 Grafana Datasource Provisioning
Abschnitt betitelt „3.3 Grafana Datasource Provisioning“Lege folgende Datei in deinem Projektordner an. Sie wird dann von Docker in den Grafana-Container hineingemountet.
(grafana/provisioning/datasources/datasource.yml)
apiVersion: 1
datasources: - name: InfluxDB_v2 type: influxdb access: proxy url: http://influxdb:8086 jsonData: version: Flux organization: school defaultBucket: sensors secureJsonData: token: school-super-tokenGrafana erwartet für InfluxDB 2.x (Flux) u. a. Organization/Bucket/Token.
4) Container Stack starten & Checks
Abschnitt betitelt „4) Container Stack starten & Checks“Im Projekt-Ordner influx-grafana-lab/:
- Starte den Container Stack mit
docker compose up -d - Prüfe mit
docker compose ps, ob beide Container laufen.
Wenn beide Container laufen, dann sollte die UI im Browser erreichbar sein:
- InfluxDB UI:
http://localhost:8086 - Grafana UI:
http://localhost:3000(bzw. die verwendete Portnummer) Verwende beim ersten Login: user/password = admin/admin und setze ein neues Passwort.
5) CSV-Import in InfluxDB
Abschnitt betitelt „5) CSV-Import in InfluxDB“InfluxDB kann CSV-Files über die Browser-GUI oder über influx write importieren.
Da InfluxDB ein spezielles annotated CSV-Format erwartet, müssen Header-Optionen angegeben werden, die die Datentypen und Spaltennamen definieren.
Details zum CSV-Import-Format: https://docs.influxdata.com/influxdb/cloud/reference/syntax/annotated-csv/#annotated-csv-in-flux
5.1 Import über einen CLI-Container (ohne lokale Installation)
Abschnitt betitelt „5.1 Import über einen CLI-Container (ohne lokale Installation)“Damit der Influx-Client nicht auf der lokalen Maschine installiert werden muss, kann man einfach einen Container für den Import erstellen und verwenden, der nach dem Import sofort wieder gelöscht wird (—rm).
Das benötigte CSV-File für den Import wird nicht in den Container kopiert sondern einfach nur gemountet. Das ist schneller und funktioniert auch für große Datenmengen.
Das CSV liegt z. B. in ./data/MOCK_DATA.csv.
PowerShell:
docker run --rm -it ` --network influx-grafana-lab_default ` -v "${PWD}/data:/data" ` influxdb:2 ` influx write ` --host http://influxdb:8086 ` --org school ` --bucket sensors ` --token school-super-token ` --format csv ` --header "#datatype measurement,dateTime:RFC3339,tag,tag,double,double,long,long" ` --header "_measurement,time,building,device,temperature_c,humidity_rh,co2_ppm,power_w" ` --skipHeader 1 ` --file /data/MOCK_DATA.csvFür z.B. Bash/Linux ersetze ${PWD} durch $(pwd).
Erklärung der Header-Optionen:
#datatypedefiniert die Typen:measurement(Messungsname),dateTime:RFC3339(Zeitstempel),tag(für Gruppierung),double/long(Zahlen)- Zweiter Header listet die exakten Spaltennamen aus der CSV auf
--skipHeader 1überspringt die CSV-Header-Zeile beim Import
Ein Import mit lokal installiertem influx CLI funktioniert analog, nur ohne docker run .... Details siehe https://docs.influxdata.com/influxdb/v2/tools/influx-cli/?t=Linux
5.2 Überprüfung des Imports
Abschnitt betitelt „5.2 Überprüfung des Imports“Überprüfe nach dem Import per CLI oder mit dem Data Explorer über die InfluxDB-UI, ob der Import erfolgreich war.
Per CLI:
docker exec influxdb influx query 'from(bucket:"sensors") |> range(start:-2y) |> count()' --token school-super-tokenPer Web-UI (Data Explorer):
- Bucket:
sensors - Measurement:
sensors - Field: z.B.
temperature_c - building: z.B.
E101 - device: z.B.
device1 - Zeitraum:
Past 1 year(da die Mock-Daten zufällige Zeitstempel haben)
Wenn du Daten von der influx query erhälst bzw. im Data Explorer als Verlauf über die Zeit siehst, dann war der Import OK.
6) Visualisierung in Grafana
Abschnitt betitelt „6) Visualisierung in Grafana“Öffne Grafana: http://localhost:3000 bzw. über das festgelegte Port
6.1 Datenquelle überprüfen
Abschnitt betitelt „6.1 Datenquelle überprüfen“- Connections → Data sources
- Datasource InfluxDB_v2 auswählen
- Ganz unten auf Test klicken.
Wenn „Data source is working“ → OK
6.2 Dashboard und Panel anlegen
Abschnitt betitelt „6.2 Dashboard und Panel anlegen“Nun kannst du in Grafana ein neues Dashboard erstellen:
- Dashboards → New → New dashboard
- Add visualization
Wichtige Panel-Settings gleich einstellen:
Im Panel-Editor:
-
Data source:
InfluxDB_v2 -
Time range: Oben rechts im Dashboard passend auf z.B. “Previous week” oder “Previous year” etc. setzen.
-
Panel-Typ: Visualization wählen (Time series / Stat / Table)
-
Query: passende Influx-Query einfügen und mit dem Query inspector überprüfen.
Beispiel-Flux-Query (als Vorlage)
from(bucket: "sensors")|> range(start: -1y)|> filter(fn: (r) => r._measurement == "sensors")|> filter(fn: (r) => r._field == "temperature_c")|> group(columns: ["building"])
Danach kannst du zum neuen Dashboard wechseln, wo die erstellten Panels angezeigt werden.
6.3 Panels
Abschnitt betitelt „6.3 Panels“Erstelle folgende Panels:
- Time series Panel:
temperature_cüber Zeit- Gruppierung nach
building
- Gruppierung nach
- Time series Panel:
co2_ppmüber Zeit- Filter: nur
building = "E101"
- Filter: nur
- Stat Panel: aktueller Wert von
humidity_rhfür ein Gebäude (z. B.LAB1) - Table Panel: letzte Messwerte (Top 20) mit Spalten
time,building,device,temperature_c,co2_ppm
7) Abgabe Teil 1
Abschnitt betitelt „7) Abgabe Teil 1“Abzugebende Artefakte
- verwendetes
docker-compose.yml - verwendetes
grafana/provisioning/datasources/datasource.yml - CSV-Schema-Beschreibung inkl. Header bzw die ersten 5 Zeilen vom CSV.
- Pro Panel
- Screenshot vom Grafana-Dashboard
- kurze Beschreibung der Panels
- Flux-Query
- weitere benötigte Einstellungen
- Kurzes
README.md:- alle verwendeten Docker Commands
- verwendetes Import Command
8) Optional: Live Daten mit Node Red
Abschnitt betitelt „8) Optional: Live Daten mit Node Red“InfluxDB kann auch als Puffer-Datenbank zur Visualisierung von Live-Daten verwendet werden.
Die Daten müssen dazu fortlaufend aus einer Datenquelle in die InfluxDB geschrieben werden und werden dann mit Grafana visualisiert. Veraltete Daten werden automatisch über die Retention Policy gelöscht.
Das funktioniert z.B.
- mit einem Python-Skript
- mit dem Telegraf-Agent der InfluxDB
- oder flexibel und ohne Coding mit Node Red
Crypto-Preis fortlaufend visualisieren
Abschnitt betitelt „Crypto-Preis fortlaufend visualisieren“Für dynamische Werte eignen sich Kurse von Cryptowährungen, die z.B. über die Binance API abgerufen werden können.
8.1 Bucket erstellen
Abschnitt betitelt „8.1 Bucket erstellen“Erstelle in der InfluxDB einen weiteren Bucket crypto mit 30 Tagen Vorhaltezeit.
docker exec influxdb influx bucket create --name crypto --org school --token school-super-token --retention 30d8.2 Node Red Service erstellen
Abschnitt betitelt „8.2 Node Red Service erstellen“Erweitere den Docker Stack um ein Node Red Service:
nodered: image: nodered/node-red:latest container_name: nodered ports: - "1880:1880" environment: - INFLUX_ORG=school - INFLUX_BUCKET=crypto - INFLUX_TOKEN=school-super-token - INFLUX_URL=http://influxdb:8086 volumes: - ./nodered-data:/data depends_on: - influxdb restart: unless-stoppedUnd starte den Stack mit dem neuen Service:
docker compose up -d8.3 Node-RED Flow aufbauen
Abschnitt betitelt „8.3 Node-RED Flow aufbauen“Öffne Node-RED: [http://localhost:1880]
Importiere diesen fertigen Flow (Menü → Import, via Clipboard):
[ { "id": "inject_crypto", "type": "inject", "name": "Alle 5 Sekunden", "props": [], "repeat": "5", "crontab": "", "once": true, "onceDelay": 0.1, "topic": "", "x": 140, "y": 100, "wires": [["http_binance"]] }, { "id": "http_binance", "type": "http request", "name": "Binance API", "method": "GET", "ret": "obj", "url": "https://api.binance.com/api/v3/ticker/price?symbols=[\"BTCUSDT\",\"ETHUSDT\",\"BNBUSDT\",\"ADAUSDT\",\"SOLUSDT\"]", "x": 340, "y": 100, "wires": [["format_influx"]] }, { "id": "format_influx", "type": "function", "name": "Format für InfluxDB", "func": "const lines = [];\nconst timestamp = Date.now() * 1000000;\n\nfor (const coin of msg.payload) {\n const symbol = coin.symbol;\n const price = parseFloat(coin.price);\n lines.push(`crypto_price,source=binance,symbol=${symbol} price=${price} ${timestamp}`);\n}\n\nmsg.payload = lines.join(\"\\n\");\nmsg.headers = {\n 'Authorization': 'Token school-super-token',\n 'Content-Type': 'text/plain; charset=utf-8'\n};\nreturn msg;", "outputs": 1, "x": 560, "y": 100, "wires": [["http_influx"]] }, { "id": "http_influx", "type": "http request", "name": "Schreibe zu InfluxDB", "method": "POST", "ret": "txt", "url": "http://influxdb:8086/api/v2/write?org=school&bucket=crypto&precision=ns", "x": 800, "y": 100, "wires": [["debug_output"]] }, { "id": "debug_output", "type": "debug", "name": "Status", "active": true, "console": false, "complete": "payload", "x": 1020, "y": 100, "wires": [] }]8.4 Flow starten
Abschnitt betitelt „8.4 Flow starten“Rechts oben auf Deploy klicken und die Daten werden alle 5sec in die InfluxDB geschrieben.
8.5 Grafana Dashboard
Abschnitt betitelt „8.5 Grafana Dashboard“Erstelle Dashboard mit folgenden Panels:
-
Panel 1: BTC Preis (Time Series)
from(bucket: "crypto")|> range(start: -1h)|> filter(fn: (r) => r._measurement == "crypto_price")|> filter(fn: (r) => r._field == "price")|> filter(fn: (r) => r.symbol == "BTCUSDT") -
Panel 2: Alle Coins (Time Series)
from(bucket: "crypto")|> range(start: -1h)|> filter(fn: (r) => r._measurement == "crypto_price")|> filter(fn: (r) => r._field == "price") -
Panel 3: Aktueller BTC Preis (Stat)
from(bucket: "crypto")|> range(start: -5m)|> filter(fn: (r) => r._measurement == "crypto_price")|> filter(fn: (r) => r._field == "price")|> filter(fn: (r) => r.symbol == "BTCUSDT")|> last() -
Panel 4: Preis-Tabelle (Table)
from(bucket: "crypto")|> range(start: -1m)|> filter(fn: (r) => r._measurement == "crypto_price")|> filter(fn: (r) => r._field == "price")|> last()|> group()
9) Abgabe Teil 2
Abschnitt betitelt „9) Abgabe Teil 2“Abzugebende Artefakte
- erweitertes
docker-compose.yml - Pro Panel
- Screenshot vom Grafana-Dashboard
- kurze Beschreibung der Panels
- Flux-Query
- weitere benötigte Einstellungen
README.mdergänzen:- alle verwendeten Docker Commands