1. Warum überhaupt Monitoring?
Das klassische Szenario
Es ist Sonntagabend, 23:47 Uhr. Dein Handy klingelt. "Die Website ist down!" - "Seit wann?" - "Keine Ahnung, könnte schon Stunden sein..." Kommt dir das bekannt vor?
Monitoring ist nicht nur „nice to have“ - es ist essentiell für jeden Server, der mehr als ein Hobby-Projekt ist. Aber es geht nicht nur um „läuft der Server noch?“. Echtes Monitoring zeigt dir:
🔍 Trends erkennen
CPU-Last steigt kontinuierlich? Vielleicht läuft da ein Memory Leak, der in zwei Wochen zum Problem wird.
Disk-Space füllt sich langsam? Besser jetzt aufräumen als wenn's zu spät ist.
Response-Zeiten werden schlechter? Zeit für Optimierung, bevor User abspringen.
⚡ Probleme vor dem Crash finden
RAM bei 95%? Alert kommt, bevor der OOM-Killer zuschlägt.
Disk I/O explodiert? Du siehst es, bevor alles langsam wird.
Netzwerk-Timeouts? Diagnose in Echtzeit statt Ratespiele.
Was ich in 5 Jahren gelernt habe
Ich betreibe seit 2019 mehrere Server (Raspberry Pis, VPS, Dedicated Server) und hatte alle klassischen Probleme:
- 2020: Raspberry Pi überhitzt regelmäßig im Sommer → Hätte ich mit Temp-Monitoring sofort gesehen
- 2021: WordPress-Site wird langsam über Wochen → MySQL slow queries, aber erst nach User-Beschwerden erkannt
- 2022: Docker-Container läuft voll, lädt aber weiter Daten → Festplatte nach 3 Tagen voll
- 2023: API-Response-Zeiten verdoppeln sich schleichend → Erst nach Monitoring-Setup erkannt: Database-Connection-Pool zu klein
Das Muster: Alle Probleme waren schleichend und hätten mit Monitoring Wochen früher erkannt werden können.
Was richtiges Monitoring leistet
Proaktiv statt reaktiv: Du siehst Probleme kommen, bevor sie kritisch werden.
Datenbasierte Entscheidungen: „Brauchen wir mehr RAM?“ - Schau ins Dashboard statt zu raten.
Optimierung mit Zahlen: Welche Änderung bringt wirklich was? Die Metriken zeigen es.
Compliance & SLAs: „Uptime 99.9%“ ist messbar, nicht nur ein Versprechen.
2. Den TIG-Stack verstehen
TIG steht für Telegraf, InfluxDB, Grafana - die drei Komponenten unseres Monitoring-Stacks. Aber warum gerade diese Kombination? Und warum nicht einfach ein „All-in-One“-Tool?
Die Philosophie: Jedes Tool macht eine Sache richtig
InfluxDB
Speichert Zeitreihendaten extrem effizient. 1 Million Datenpunkte? Kein Problem.
Telegraf
Sammelt alles: CPU, RAM, Docker, APIs, Logs. 200+ Input-Plugins.
Grafana
Macht aus Daten verständliche Dashboards. Alerts inklusive.
Warum nicht Prometheus + Node Exporter?
Gute Frage! Prometheus ist definitiv der Standard in der Kubernetes-Welt. Aber für kleinere Setups (1-10 Server) hat der TIG-Stack einige Vorteile:
TIG-Stack Vorteile
- Einfachere Installation: Ein docker-compose, läuft
- InfluxDB ist SQL-ähnlich:
SELECT * FROM cpu WHERE time > now()-1h - Telegraf ist unkompliziert: Config-File, Plugin an, fertig
- Bessere Datenretention: InfluxDB komprimiert brutal gut
Prometheus Vorteile
- Industry Standard: Jeder Cloud-Provider unterstützt es
- Kubernetes Integration: Native Service Discovery
- PromQL: Mächtige Query Language
- Ecosystem: Mehr Exporter, mehr Community
Meine Empfehlung: TIG für Homelab/kleinere Setups, Prometheus für Production/Kubernetes.
Wie die Daten fließen
2025-01-12T15:30:00Z mem_used_bytes=2147483648 host=server1
Wichtig: Retention Policy verstehen
InfluxDB speichert nicht grundsätzlich endlos. Könnte es aber! Standard: 1 Jahr. Das bedeutet: Daten werden automatisch nach 365 Tagen gelöscht. Für Homelab meist okay, für Business kritisch zu planen. Aber für Raspberry Pi mit nur einer SD-Karte, auch nicht die beste Idee. ;-)
3. InfluxDB: Die Zeitreihendatenbank
InfluxDB ist das Herzstück unseres Setups. Hier landen alle Metriken, und die Art wie wir es konfigurieren entscheidet über Performance und Speicherverbrauch. Ich zeige dir, was ich in der Praxis gelernt habe.
Vorbereitung: Verzeichnisstruktur
# Hauptverzeichnis für Monitoring-Stack
mkdir -p ~/monitoring/{influxdb,telegraf,grafana}
cd ~/monitoring
# InfluxDB Datenverzeichnisse
mkdir -p influxdb/{data,config}
# Konfigurationsverzeichnisse
mkdir -p telegraf/config
mkdir -p grafana/{data,dashboards,provisioning}
# Berechtigungen setzen (wichtig für Container!)
sudo chown -R 1000:1000 ~/monitoring
chmod -R 755 ~/monitoring
# Struktur prüfen
sudo apt install tree
tree ~/monitoring
# monitoring/
# ├── influxdb/
# │ ├── data/
# │ └── config/
# ├── telegraf/
# │ └── config/
# └── grafana/
# ├── data/
# ├── dashboards/
# └── provisioning/InfluxDB 2.x Container starten
# ~/monitoring/docker-compose.yml erstellen
cat > docker-compose.yml << 'EOF'
version: '3.8'
services:
influxdb:
image: influxdb:2.7-alpine
container_name: influxdb
restart: unless-stopped
ports:
- "8086:8086"
volumes:
- ./influxdb/data:/var/lib/influxdb2
- ./influxdb/config:/etc/influxdb2
environment:
# Initial Setup - WICHTIG: Nur beim ersten Start
- DOCKER_INFLUXDB_INIT_MODE=setup
- DOCKER_INFLUXDB_INIT_USERNAME=admin
- DOCKER_INFLUXDB_INIT_PASSWORD=monitoring2025!
- DOCKER_INFLUXDB_INIT_ORG=homelab
- DOCKER_INFLUXDB_INIT_BUCKET=metrics
- DOCKER_INFLUXDB_INIT_RETENTION=365d
- DOCKER_INFLUXDB_INIT_ADMIN_TOKEN=super-secret-auth-token-change-me
networks:
- monitoring
networks:
monitoring:
driver: bridge
EOF
# InfluxDB starten
docker compose up -d influxdbWichtige Security-Hinweise
Token ändern: `DOCKER_INFLUXDB_INIT_ADMIN_TOKEN` ist dein Master-Key. Generiere einen sicheren Token!
Passwort sicher: `monitoring2025!` nur als Beispiel - wähle ein starkes Passwort.
Port 8086: Nur bei Bedarf extern zugänglich machen (Firewall!)
Ersten Start prüfen und konfigurieren
# Container-Status prüfen docker compose ps # Sollte zeigen: influxdb running # Logs prüfen - wichtig für Troubleshooting docker compose logs influxdb # InfluxDB UI öffnen Öffne: http://YOUR-SERVER-IP:8086 Login: admin / monitoring2025! (was du natürlich anpassen solltest!) # CLI-Test (optional) docker exec -it influxdb influx auth list # Sollte deinen Token zeigen
Warum diese Konfiguration?
Retention Policy: 365 Tage
Warum 1 Jahr? Für Monitoring brauchst du längere Trends. Beispiele aus der Praxis:
- Saisonale Patterns: Website-Traffic im Dezember vs. Januar
- Hardware-Trends: RAM-Verbrauch steigt über Monate
- Kapazitätsplanung: „Wann ist die Festplatte voll?“ → Trend über 6 Monate
Alpine Image: Ressourcenschonend
InfluxDB 2.7-alpine anstelle eines Standard-Images: Nur 150MB Speicherverbrauch statt 300MB. Besonders wichtig bei Raspberry Pi oder VPS mit begrenztem RAM.
InfluxDB läuft! Nächste Schritte
✅ Container läuft stabil
✅ Web-UI ist erreichbar
✅ Admin-User wurde erstellt
✅ Default-Bucket "metrics" existiert
🔄 Jetzt: Telegraf konfigurieren für Datensammlung
4. Telegraf: Der Datensammler
Telegraf ist der Arbeiter in unserem Stack. Er sammelt alle 10 Sekunden Daten von überall und schickt sie an InfluxDB. Aber welche Plugins brauchst du wirklich? Und welche fressen nur Ressourcen?
Basis-Konfiguration: Die wichtigsten Plugins
# ~/monitoring/telegraf/config/telegraf.conf cat > ~/monitoring/telegraf/config/telegraf.conf << 'EOF' [global_tags] # Wichtig: Eindeutige Identifikation des Servers host = "$HOSTNAME" datacenter = "homelab" [agent] interval = "10s" # Alle 10 Sekunden sammeln round_interval = true # Auf volle 10s runden (wichtig für Grafana!) metric_batch_size = 1000 # Batch-Größe für bessere Performance metric_buffer_limit = 10000 collection_jitter = "0s" # Kein Jitter bei einzelnem Host flush_interval = "10s" # Sofort an InfluxDB senden flush_jitter = "0s" # OUTPUT: Verbindung zu InfluxDB [[outputs.influxdb_v2]] urls = ["http://influxdb:8086"] token = "super-secret-auth-token-change-me" # Dein InfluxDB Token organization = "homelab" bucket = "metrics" timeout = "5s" # INPUT 1: System-Metriken (CPU, RAM, Disk) [[inputs.cpu]] percpu = true # Pro CPU-Core einzeln totalcpu = true # + Gesamt-CPU collect_cpu_time = false # CPU-Zeit brauchen wir nicht report_active = false # Active/Idle-Ratio nicht nötig [[inputs.disk]] ignore_fs = ["tmpfs", "devtmpfs", "devfs", "iso9660", "overlay", "aufs", "squashfs"] # Nur echte Filesysteme, nicht temporäre [[inputs.diskio]] # Disk I/O ist oft der Flaschenhals [[inputs.kernel]] # Kernel-Statistiken [[inputs.mem]] # RAM-Verbrauch [[inputs.processes]] # Anzahl Prozesse [[inputs.swap]] # Swap-Verbrauch (wichtig bei wenig RAM) [[inputs.system]] # System Load, Uptime etc. # INPUT 2: CPU-Temperatur (wichtig für Raspberry Pi & Co.) [[inputs.file]] files = ["/sys/class/thermal/thermal_zone0/temp"] name_override = "cpu_temperature" data_format = "value" data_type = "integer" [[inputs.exec]] # Für ein 32bit System (welches überwacht werden soll) commands = ["/opt/vc/bin/vcgencmd measure_temp"] # Oder für ein 64bit System (welches überwacht werden soll), dann die Raute(#) entfernen und bei 32bit die Raute hinzufügen # commands = ["/usr/bin/vcgencmd measure_temp"] name_override = "cpu_temperature" data_format = "value" data_type = "string" # INPUT 3: Netzwerk [[inputs.net]] interfaces = ["eth*", "en*", "wlan*"] # Nur echte Interfaces ignore_protocol_stats = false [[inputs.netstat]] # TCP-Verbindungen # INPUT 4: Docker (wenn vorhanden) [[inputs.docker]] endpoint = "unix:///var/run/docker.sock" gather_services = false # Services nicht nötig container_names = [] # Alle Container container_name_include = [] container_name_exclude = [] timeout = "5s" perdevice = true # Per Container einzeln total = false # Gesamt nicht nötig EOF
Telegraf zu Docker Compose hinzufügen
# ~/monitoring/docker-compose.yml erweitern
# WICHTIG: Stelle sicher, dass die Einrückung korrekt ist!
cat >> ~/monitoring/docker-compose.yml << 'EOF'
telegraf:
image: telegraf:1.28-alpine
container_name: telegraf
restart: unless-stopped
volumes:
# Konfiguration
- ./telegraf/config/telegraf.conf:/etc/telegraf/telegraf.conf:ro
# Host-System-Zugriff für Metriken
- /:/hostfs:ro
- /etc:/hostfs/etc:ro
- /proc:/hostfs/proc:ro
- /sys:/hostfs/sys:ro
- /var:/hostfs/var:ro
- /run:/hostfs/run:ro
# Docker-Socket für Container-Metriken
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
# Wichtig: Host-Pfade für System-Metriken
- HOST_ETC=/hostfs/etc
- HOST_PROC=/hostfs/proc
- HOST_SYS=/hostfs/sys
- HOST_VAR=/hostfs/var
- HOST_RUN=/hostfs/run
- HOST_MOUNT_PREFIX=/hostfs
networks:
- monitoring
depends_on:
- influxdb
user: telegraf:docker # Docker-Gruppe für Socket-Zugriff
EOF
# Alternative: Vollständige docker-compose.yml erstellen
# Falls das Append nicht funktioniert, erstelle die Datei komplett neu:
cat > ~/monitoring/docker-compose.yml << 'EOF'
version: '3.8'
services:
influxdb:
image: influxdb:2.7-alpine
container_name: influxdb
restart: unless-stopped
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=monitoring2025!
- DOCKER_INFLUXDB_INIT_ORG=homelab
- DOCKER_INFLUXDB_INIT_BUCKET=metrics
- DOCKER_INFLUXDB_INIT_RETENTION=365d
- DOCKER_INFLUXDB_INIT_ADMIN_TOKEN=super-secret-auth-token-change-me
networks:
- monitoring
telegraf:
image: telegraf:1.28-alpine
container_name: telegraf
restart: unless-stopped
volumes:
- ./telegraf/config/telegraf.conf:/etc/telegraf/telegraf.conf:ro
- /:/hostfs:ro
- /etc:/hostfs/etc:ro
- /proc:/hostfs/proc:ro
- /sys:/hostfs/sys:ro
- /var:/hostfs/var:ro
- /run:/hostfs/run:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- HOST_ETC=/hostfs/etc
- HOST_PROC=/hostfs/proc
- HOST_SYS=/hostfs/sys
- HOST_VAR=/hostfs/var
- HOST_RUN=/hostfs/run
- HOST_MOUNT_PREFIX=/hostfs
networks:
- monitoring
depends_on:
- influxdb
user: telegraf:docker
networks:
monitoring:
driver: bridge
EOFDocker-Socket Security
Problem: Docker-Socket = Root-Zugriff auf Host. Telegraf braucht ihn für Container-Metriken.
Lösung: Docker-Gruppe ID finden und verwenden
# 1. Docker-Gruppe ID prüfen cat /etc/group | grep docker # Beispiel Output: docker:x:999:user # 2. Falls Docker-Gruppe nicht existiert, erstellen: sudo groupadd docker # 3. Aktuellen User zur Docker-Gruppe hinzufügen sudo usermod -a -G docker $USER # 4. docker-compose.yml anpassen - user-Zeile ändern: # user: "telegraf:999" # 999 = docker group id aus Schritt 1 # 5. Telegraf neustarten docker compose down docker compose up -d
Alternative: Docker-Plugin deaktivieren (einfacher)
# 1. docker-compose.yml anpassen - user-Zeile entfernen: # user: telegraf:docker # Diese Zeile auskommentieren oder löschen # 2. telegraf.conf anpassen - Docker-Input auskommentieren: # [[inputs.docker]] # endpoint = "unix:///var/run/docker.sock" # ... rest der docker config # 3. Telegraf neustarten docker compose down docker compose up -d
Empfehlung: Für den Start: Alternative verwenden (nur System-Metriken). Später kann Docker-Monitoring hinzugefügt werden.
Warum diese Plugin-Auswahl?
Telegraf hat 200+ Input-Plugins. Aber 90% brauchst du nie. Hier meine Erfahrung aus 5 Jahren:
✅ Essentiell (immer aktivieren)
- cpu, mem, disk: Die großen Drei
- diskio: I/O-Bottlenecks finden
- system: Load Average, Uptime
- net: Netzwerk-Traffic
- docker: Container-Ressourcen
- cpu_temperature: Überhitzung verhindern
❌ Überflüssig (vermeide diese)
- logparser: Macht InfluxDB langsam
- ping: Netzwerk-Spam
- sensors: Nur bei Hardware-Problemen
- iptables: Meist nutzlos
- snmp: Nur für Enterprise-Hardware
💡 CPU-Temperatur: Warum zwei Inputs?
[[inputs.file]]: Liest direkt aus /sys/class/thermal/thermal_zone0/temp (Linux-Systeme)
[[inputs.exec]]: Verwendet vcgencmd (Raspberry Pi spezifisch)
Beide: Überschreiben den Namen zu "cpu_temperature" für einheitliche Metriken
Wichtig: Nur eine Methode funktioniert pro System - das ist normal!
Telegraf starten und testen
# Telegraf starten cd ~/monitoring docker compose up -d telegraf # Logs prüfen - wichtig! docker compose logs telegraf # Sollte zeigen: "Starting Telegraf " und keine Errors # Verbindung zu InfluxDB prüfen docker compose logs telegraf | grep "Error" # Sollte NICHTS zeigen # Container-Status docker compose ps # Beide Container sollten "Up" sein # Quick-Test: Daten in InfluxDB angekommen? docker exec -it influxdb influx query 'from(bucket:"metrics") |> range(start:-1m) |> limit(n:5)' # Sollte aktuelle Metriken zeigen
Telegraf läuft! Was passiert jetzt?
✅ Alle 10 Sekunden sammelt Telegraf System-Metriken
✅ Daten landen automatisch in InfluxDB bucket "metrics"
✅ Measurements: cpu, mem, disk, diskio, net, docker...
🔄 Nächster Schritt: Grafana für schöne Dashboards
5. Grafana: Aus Daten werden Dashboards
Grafana macht aus nackten Zahlen verständliche Visualisierungen. Aber: Es kann alles - und dadurch wird es schnell überwältigend. Ich zeige dir, wie du effektive Dashboards baust, nicht nur „bunte Diagramme“.
Grafana Container hinzufügen
# ~/monitoring/docker-compose.yml - Vollständige Version
# WICHTIG: Korrekte YAML-Einrückung verwenden!
cat > ~/monitoring/docker-compose.yml << 'EOF'
services:
influxdb:
image: influxdb:2.7-alpine
container_name: influxdb
restart: unless-stopped
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=monitoring2025!
- DOCKER_INFLUXDB_INIT_ORG=homelab
- DOCKER_INFLUXDB_INIT_BUCKET=metrics
- DOCKER_INFLUXDB_INIT_RETENTION=365d
- DOCKER_INFLUXDB_INIT_ADMIN_TOKEN=super-secret-auth-token-change-me
networks:
- monitoring
telegraf:
image: telegraf:1.28-alpine
container_name: telegraf
restart: unless-stopped
volumes:
- ./telegraf/config/telegraf.conf:/etc/telegraf/telegraf.conf:ro
- /:/hostfs:ro
- /etc:/hostfs/etc:ro
- /proc:/hostfs/proc:ro
- /sys:/hostfs/sys:ro
- /var:/hostfs/var:ro
- /run:/hostfs/run:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- HOST_ETC=/hostfs/etc
- HOST_PROC=/hostfs/proc
- HOST_SYS=/hostfs/sys
- HOST_VAR=/hostfs/var
- HOST_RUN=/hostfs/run
- HOST_MOUNT_PREFIX=/hostfs
networks:
- monitoring
depends_on:
- influxdb
user: telegraf:docker
grafana:
image: grafana/grafana:10.2.2
container_name: grafana
restart: unless-stopped
ports:
- "3000:3000"
volumes:
- ./grafana/data:/var/lib/grafana
- ./grafana/provisioning:/etc/grafana/provisioning
environment:
# Security: Default-Admin ändern
- GF_SECURITY_ADMIN_USER=admin
- GF_SECURITY_ADMIN_PASSWORD=grafana2025!
# Performance: Memory-Limits
- GF_SERVER_ROOT_URL=http://localhost:3000
- GF_ANALYTICS_REPORTING_ENABLED=false
- GF_ANALYTICS_CHECK_FOR_UPDATES=false
# Security: Anonymous Access disabled
- GF_AUTH_ANONYMOUS_ENABLED=false
networks:
- monitoring
depends_on:
- influxdb
user: "472:472" # Grafana User/Group
networks:
monitoring:
driver: bridge
EOF
# Grafana-Verzeichnisse erstellen und Permissions setzen
mkdir -p ~/monitoring/grafana/data
mkdir -p ~/monitoring/grafana/provisioning
# Permissions für Grafana setzen (wichtig!)
sudo chown -R 472:472 ~/monitoring/grafana/data
sudo chown -R 472:472 ~/monitoring/grafana/provisioning
# Vollständiger Stack starten
docker compose down
docker compose up -d
# Alle Container prüfen
docker compose ps
# Sollte zeigen: influxdb, telegraf, grafana alle "Up"Grafana Permissions-Problem
Problem: Grafana läuft als User ID 472, aber lokale Verzeichnisse gehören deinem User
Lösung: Verzeichnisse dem Grafana-User geben
Falls du den Fehler bereits hast:
# Container stoppen docker compose down # Verzeichnisse erstellen und Permissions setzen mkdir -p ~/monitoring/grafana/data mkdir -p ~/monitoring/grafana/provisioning sudo chown -R 472:472 ~/monitoring/grafana/data sudo chown -R 472:472 ~/monitoring/grafana/provisioning # Container neu starten docker compose up -d # Logs prüfen docker compose logs grafana
Alternative: Falls du keine sudo-Rechte hast, entferne die `user: "472:472"` Zeile aus der docker-compose.yml
InfluxDB als Datenquelle einrichten
1. Grafana Web-UI öffnen:
http://YOUR-SERVER-IP:3000
Login: admin / grafana2025!
2. Data Source hinzufügen:
- ⚙️ Connections → Data Sources
- Add data source → InfluxDB
- Query Language: Flux (nicht InfluxQL!)
- URL:
http://influxdb:8086 - Organization:
homelab - Token:
super-secret-auth-token-change-me - Default Bucket:
metrics
3. Test & Save
Sollte "Data source is working" zeigen
Flux vs. InfluxQL: Warum Flux?
InfluxQL: SQL-ähnlich, einfach, aber limitiert
Flux: Funktional, mächtiger, aber steile Lernkurve
Realität 2025: InfluxDB 2.x pusht Flux. InfluxQL wird weniger unterstützt.
Mein Tipp: Flux lernen. Ich zeige dir die wichtigsten Queries.
6. Effektive Dashboards erstellen
Das Problem: Die meisten Grafana-Dashboards sehen aus wie Weihnachtsbäume - bunt, aber unübersichtlich. Ich zeige dir Dashboard-Design-Prinzipien, die ich in der Praxis gelernt habe.
Dashboard-Philosophie: Das "5-Sekunden-Prinzip"
Regel: In 5 Sekunden muss klar sein: "Läuft alles normal oder gibt es ein Problem?"
✅ Gutes Dashboard
- Top-Row: Overall Health (CPU, RAM, Disk)
- Farben: Grün = OK, Gelb = Warning, Rot = Critical
- Größen: Wichtiges groß, Details klein
- Zeitrange: Last 1h als Standard
❌ Schlechtes Dashboard
- Info-Overload: 50 Panels mit allem
- Bunte Chaos: Jede Metrik andere Farbe
- Skalierung: Axis von 0-100, Werte bei 2-5
- Veraltung: Dashboard seit 2 Jahren nicht angepasst
Essential Dashboard: System Overview
1. Neues Dashboard: ➕ Create → Dashboard
Panel 1: CPU Temperature (Stat Panel)
// Flux Query für CPU Temperature
from(bucket: "${bucket}")
|> range(start: v.timeRangeStart, stop: v.timeRangeStop)
|> filter(fn: (r) => r["_measurement"] == "cpu_temperature")
|> filter(fn: (r) => r["_field"] == "value")
|> filter(fn: (r) => r["host"] =~ /${host}/ )
|> map(fn: (r) => ({ r with _value: r._value / 1000 }))
|> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)
|> yield(name: "mean")
// Visualization: Stat
// Thresholds: 0-75 Green, 75-80 Yellow, 80+ Red
// Unit: CelsiusPanel 2: CPU Usage (Gauge Panel)
// Flux Query für CPU Percentage
from(bucket: "${bucket}")
|> range(start: v.timeRangeStart, stop: v.timeRangeStop)
|> filter(fn: (r) => r._measurement == "cpu" and r.host == "${host}" and r._field == "usage_idle" and r.cpu == "cpu-total")
|> aggregateWindow(every: v.windowPeriod, fn: last, createEmpty: false)
|> pivot(rowKey: ["_time"], columnKey: ["_field"], valueColumn: "_value")
|> map(fn: (r) => ({r: r.usage_idle * -1.0 + 100.0}))
// Visualization: Gauge
// Thresholds: 0-70 Green, 70-80 Yellow, 80+ Red
// Unit: Percent (0-100)Panel 3: RAM Usage (Gauge Panel)
// Flux Query für RAM Percentage
from(bucket: "${bucket}")
|> range(start: v.timeRangeStart, stop: v.timeRangeStop)
|> filter(fn: (r) => r["_measurement"] == "mem")
|> filter(fn: (r) => r["_field"] == "used_percent")
|> filter(fn: (r) => r.host == "${host}")
|> aggregateWindow(every: v.windowPeriod, fn: last, createEmpty: false)
|> yield(name: "last")
// Visualization: Gauge
// Thresholds: 0-70 Green, 70-80 Yellow, 80+ Red
// Unit: Percent (0-100)Panel 4: Disk Usage (Gauge Panel)
// Flux Query für Disk Usage
from(bucket: "${bucket}")
|> range(start: v.timeRangeStart, stop: v.timeRangeStop)
|> filter(fn: (r) => r["_measurement"] == "disk")
|> filter(fn: (r) => r.host == "${host}")
|> filter(fn: (r) => r["_field"] == "used_percent")
|> filter(fn: (r) => r["path"] == "/")
|> aggregateWindow(every: v.windowPeriod, fn: last, createEmpty: false)
|> yield(name: "last")
// Visualization: Gauge
// Thresholds: 0-70 Green, 70-80 Yellow, 80+ Red
// Unit: Percent (0-100)Panel 5: System Uptime (Stat Panel)
// Flux Query für System Uptime
from(bucket: "${bucket}")
|> range(start: v.timeRangeStart, stop: v.timeRangeStop)
|> filter(fn: (r) => r.host =~ /${host}/ and r._measurement == "system" and r._field == "uptime")
|> aggregateWindow(every: v.windowPeriod, fn: last, createEmpty: false)
|> yield(name: "last")
// Visualization: Stat
// Unit: Seconds
// Shows system uptime in secondsAlternative: Dashboard JSON importieren
Für alle, die nicht manuell erstellen möchten:
📥 Dashboard herunterladen
system-overview-dashboard.jsonEnthält 9 Panels: CPU, Memory, Disk, Load, Network, Disk I/O
Import-Schritte:
- JSON-Datei herunterladen (Button oben)
- Grafana öffnen:
http://YOUR-SERVER-IP:3000 - ➕ Create → Import → Upload JSON file
- Datei auswählen und Import klicken
- Wichtig: Data Source auswählen:
InfluxDB(deine konfigurierte Data Source) - Import bestätigen
Falls Import nicht funktioniert:
- Stelle sicher, dass die InfluxDB Data Source konfiguriert ist
- Prüfe, ob Telegraf Daten sammelt:
docker compose logs telegraf - Teste die Data Source in Grafana: Configuration → Data Sources → Test
- Falls Probleme: Verwende die manuelle Erstellung oben
Dashboard-Features:
- Top Row: CPU Temperature, CPU Usage, RAM Usage, Disk Usage (Gauge & Stat Panels)
- Bottom Row: System Uptime, Load Average, Total Processes (Stat Panels)
- Variables: Automatische Bucket- und Host-Auswahl
- Thresholds: Farbkodierte Warnungen (Grün/Gelb/Rot)
7. Intelligentes Alerting
Der Horror: Alerts um 3 Uhr nachts wegen 0,1% CPU-Anstieg. Die Realität: Nach einer Woche schaltest du alle Alerts ab. Ich zeige dir, wie du Alerts baust, die wirklich wichtig sind.
Alert-Philosophie: „Würde ich dafür nachts aufstehen?“
✅ Gute Alerts
- Disk 95% voll: In 1-2 Tagen kritisch
- RAM 90%+ für 5min: OOM-Killer droht
- Load Average 5+ für 10min: System überlastet
- Container down: Service nicht erreichbar
❌ Nervige Alerts
- CPU 70% für 30s: Normal bei Updates
- Network-Spike: YouTube-Stream startet
- RAM 80%: Linux nutzt RAM als Cache
- Disk I/O hoch: Docker-Build läuft
Essential Alerts konfigurieren
1. Alert Rule erstellen: Alerting → Alert Rules → New Rule
Alert: Disk Space Critical
// Flux Query für Disk Usage from(bucket: "metrics") |> range(start: -5m) |> filter(fn: (r) => r["_measurement"] == "disk") |> filter(fn: (r) => r["_field"] == "used_percent") |> filter(fn: (r) => r["path"] == "/") |> mean() // Condition: IS ABOVE 95 // Evaluation: every 1m for 2m // No Data: Alerting (wichtig!) // Execution Error: Alerting
2. Notification Policy: Alerting → Notification Policies
- Group by: alertname (gleiche Alerts zusammenfassen)
- Group wait: 10s (kurz warten)
- Group interval: 5m (nicht spammen)
- Repeat interval: 12h (alle 12h wiederholen)
Wichtig: Alert-Müdigkeit vermeiden
Problem: Zu viele Alerts = Alle werden ignoriert
Lösung: Maximal 5 Alert-Rules. Lieber weniger, aber wichtige.
Test-Regel: Jeder Alert muss einen konkreten Action-Plan haben
8. Real-World Troubleshooting
Die 8 Probleme, die garantiert auftreten werden. Und wie du sie löst, ohne stundenlang zu googeln.
Problem 1: „No data“ in Grafana
Symptom: Dashboard zeigt „No data“, obwohl Telegraf läuft
Ursache meist: Timestamp-Probleme oder falsche Bucket
Debug-Steps:
# 1. InfluxDB-Daten prüfen docker exec -it influxdb influx query 'buckets()' # Bucket "metrics" sollte existieren # 2. Aktuelle Daten prüfen docker exec -it influxdb influx query 'from(bucket:"metrics") |> range(start:-5m) |> limit(n:5)' # Sollte aktuelle Daten zeigen # 3. Telegraf-Logs prüfen docker compose logs telegraf | tail -20 # Auf Fehler prüfen # 4. Zeitzone-Problem lösen docker exec -it telegraf date docker exec -it influxdb date # Beide sollten gleiche Zeit zeigen
Problem 2: InfluxDB wird langsam
Symptom: Queries dauern nach 2-3 Wochen ewig
Ursache: Zu viele Series, keine Downsampling
Lösung:
# Series-Anzahl prüfen
docker exec -it influxdb influx query 'import "influxdata/influxdb/schema"
schema.measurements(bucket: "metrics")'
# Retention Policy anpassen (in InfluxDB UI)
# Data → Buckets → metrics → Edit
# Retention: 30d statt 365d für Tests
# Downsampling Task erstellen
# Data → Tasks → Create Task
task_example = '''
option task = {name: "downsample_cpu", every: 1h}
from(bucket: "metrics")
|> range(start: -2h, stop: -1h)
|> filter(fn: (r) => r._measurement == "cpu")
|> aggregateWindow(every: 1m, fn: mean)
|> to(bucket: "metrics_hourly")
''''Problem 3: Telegraf sammelt keine Docker-Metriken
Symptom: System-Metriken da, Docker-Container fehlen
Ursache meist: Docker-Socket Permissions
Fix:
# User zur docker-Gruppe hinzufügen sudo usermod -a -G docker $USER # Telegraf neustarten docker compose down docker compose up -d # Testen ob Docker-Metriken kommen docker compose logs telegraf | grep docker # Alternative: Docker-Plugin deaktivieren # Entferne [[inputs.docker]] aus telegraf.conf
Problem 4: Grafana Alert-Spam
Symptom: Hunderte Alerts wegen temporärer CPU-Spikes
Ursache: Zu niedrige Thresholds, zu kurze Evaluation-Zeiten
Alert-Tuning:
# Intelligente CPU-Alert Query
from(bucket: "metrics")
|> range(start: -10m)
|> filter(fn: (r) => r["_measurement"] == "cpu")
|> filter(fn: (r) => r["_field"] == "usage_idle")
|> filter(fn: (r) => r["cpu"] == "cpu-total")
|> map(fn: (r) => ({r with _value: 100.0 - r._value}))
|> aggregateWindow(every: 1m, fn: mean)
|> mean()
# Condition: IS ABOVE 90 for 5 minutes
# Statt: IS ABOVE 70 for 30 seconds
# Group wait: 10m (statt 30s)
# Repeat interval: 4h (statt 5m)Problem 5: Container werden nicht erkannt
Symptom: Nur Host-Metriken, keine Container-Details
Lösung: Labels und Container-Namen konfigurieren
Erweiterte Telegraf-Config:
# telegraf.conf erweitern
[[inputs.docker]]
endpoint = "unix:///var/run/docker.sock"
gather_services = false
container_names = []
container_name_include = ["*"]
container_name_exclude = ["telegraf", "grafana"]
timeout = "5s"
perdevice = true
total = true
docker_label_include = ["com.docker.compose.service"]
docker_label_exclude = []
tag_env = ["ENVIRONMENT"]
# Container-Labels in docker-compose.yml
services:
your-app:
labels:
- "monitoring=true"
- "team=backend"
environment:
- ENVIRONMENT=productionProblem 6: Hoher Speicherverbrauch
Symptom: InfluxDB braucht nach 1 Monat 8GB+ RAM
Ursache: Zu viele Metriken, keine Limits
Memory-Optimierung:
# docker-compose.yml: Memory-Limits setzen
services:
influxdb:
deploy:
resources:
limits:
memory: 2G
reservations:
memory: 512M
environment:
# InfluxDB Memory-Settings
- INFLUXD_QUERY_MEMORY_BYTES=1073741824 # 1GB
- INFLUXD_QUERY_CONCURRENCY=10
telegraf:
deploy:
resources:
limits:
memory: 512M
# telegraf.conf: Sampling reduzieren
[agent]
interval = "30s" # Statt 10s
collection_jitter = "5s" # Jitter hinzufügen
metric_buffer_limit = 5000 # Buffer kleinerProblem 7: Dashboards laden langsam
Symptom: Grafana-Dashboard braucht 30+ Sekunden zum Laden
Ursache: Ineffiziente Flux-Queries, zu große Zeiträume
Query-Optimierung:
# ❌ Langsame Query
from(bucket: "metrics")
|> range(start: -24h)
|> filter(fn: (r) => r["_measurement"] == "cpu")
|> yield()
# ✅ Optimierte Query
from(bucket: "metrics")
|> range(start: -6h)
|> filter(fn: (r) => r["_measurement"] == "cpu")
|> filter(fn: (r) => r["_field"] == "usage_idle")
|> filter(fn: (r) => r["cpu"] == "cpu-total")
|> aggregateWindow(every: 1m, fn: mean, createEmpty: false)
|> map(fn: (r) => ({r with _value: 100.0 - r._value}))
# Dashboard-Settings optimieren:
# - Max data points: 1000 (statt unlimited)
# - Min interval: 1m (statt auto)
# - Relative time: 6h (statt 24h)Problem 8: Backup & Recovery
Szenario: Server-Crash, alle Monitoring-Daten weg
Lösung: Automatische Backups einrichten
Backup-Strategie:
# backup.sh Script erstellen #!/bin/bash DATE=$(date +%Y%m%d_%H%M%S) BACKUP_DIR="/backup/monitoring" mkdir -p $BACKUP_DIR # InfluxDB Backup docker exec influxdb influx backup /tmp/backup_$DATE -t super-secret-auth-token-change-me docker cp influxdb:/tmp/backup_$DATE $BACKUP_DIR/ # Grafana Config Backup docker cp grafana:/var/lib/grafana $BACKUP_DIR/grafana_$DATE # Configs sichern cp -r ~/monitoring/telegraf $BACKUP_DIR/telegraf_$DATE cp ~/monitoring/docker-compose.yml $BACKUP_DIR/ # Alte Backups löschen (älter als 30 Tage) find $BACKUP_DIR -name "*" -mtime +30 -delete # Crontab: Täglich um 2 Uhr # 0 2 * * * /home/user/monitoring/backup.sh
9. Erweiterte Konfiguration
Wenn das Basis-Setup läuft, kannst du mit diesen Erweiterungen das System auf das nächste Level bringen.
Multi-Server Monitoring
Szenario: Du hast 3 Server (Raspberry Pi, VPS, Homeserver) und willst alle zentral überwachen.
Server 1: Zentrale InfluxDB + Grafana
# docker-compose.yml auf dem Hauptserver
version: '3.8'
services:
influxdb:
image: influxdb:2.7-alpine
ports:
- "8086:8086" # Extern erreichbar machen
environment:
- DOCKER_INFLUXDB_INIT_ADMIN_TOKEN=central-monitoring-token-2025
# ... rest der config
grafana:
image: grafana/grafana:10.2.2
ports:
- "3000:3000"
# ... rest der configServer 2+3: Nur Telegraf
# telegraf.conf auf anderen Servern
[global_tags]
host = "raspberry-pi-4" # Eindeutiger Name
location = "homelab"
role = "nas"
[[outputs.influxdb_v2]]
urls = ["http://HAUPTSERVER-IP:8086"]
token = "central-monitoring-token-2025"
organization = "homelab"
bucket = "metrics"
# docker-compose.yml (minimal)
version: '3.8'
services:
telegraf:
image: telegraf:1.28-alpine
volumes:
- ./telegraf.conf:/etc/telegraf/telegraf.conf:ro
# ... volume mounts für host accessCustom Metriken sammeln
Neben System-Metriken willst du vielleicht Business-Metriken: Website-Besucher, E-Mail-Queue, API-Response-Times, etc.
HTTP-Endpoints überwachen
# telegraf.conf erweitern
[[inputs.http_response]]
urls = [
"https://wolfcoder.de",
"https://api.wolfcoder.de/health",
"http://localhost:3000"
]
response_timeout = "5s"
method = "GET"
follow_redirects = true
# Optional: HTTP Basic Auth
# username = "monitoring"
# password = "secret123"MySQL/PostgreSQL überwachen
# MySQL Monitoring [[inputs.mysql]] servers = ["monitoring:password123@tcp(mysql:3306)/"] metric_version = 2 # Welche Metriken sammeln gather_process_list = true gather_user_statistics = true gather_info_schema_auto_inc = true gather_innodb_metrics = true gather_slave_lag = false # PostgreSQL Alternative [[inputs.postgresql]] address = "postgres://monitoring:password123@postgres:5432/postgres?sslmode=disable" outputaddress = "postgres" databases = ["app_production", "analytics"]
Nginx/Apache Log-Parsing
# Nginx Status-Modul
[[inputs.nginx]]
urls = ["http://nginx/nginx_status"]
response_timeout = "5s"
# Log-File parsen (Vorsicht: Performance!)
[[inputs.logparser]]
files = ["/var/log/nginx/access.log"]
from_beginning = false
# Common Log Format parsen
[inputs.logparser.grok]
patterns = ['''%{COMBINED_LOG_FORMAT}''']
measurement = "nginx_access"
timezone = "Europe/Berlin"Notification-Channels erweitern
Standard-Grafana-Notifications sind langweilig. Hier richtig coole Alerts erstellen:
Discord Webhook einrichten
# 1. Discord-Server → Server-Einstellungen → Integrationen → Webhooks
# 2. Webhook erstellen, URL kopieren
# 3. Grafana → Alerting → Contact Points → New Contact Point
# Discord Webhook URL:
# https://discord.com/api/webhooks/123456789/AbCdEfGhIjKlMnOpQrStUvWx
# Message Template:
{
"embeds": [{
"title": "🚨 Monitoring Alert",
"description": "{{ range .Alerts }}{{ .Annotations.summary }}{{ end }}",
"color": {{ if eq .Status "firing" }}16711680{{ else }}65280{{ end }},
"fields": [
{"name": "Server", "value": "{{ .GroupLabels.host }}", "inline": true},
{"name": "Status", "value": "{{ .Status }}", "inline": true}
],
"timestamp": "{{ .CommonAnnotations.timestamp }}"
}]
}E-Mail mit SMTP
# Grafana SMTP in docker-compose.yml
services:
grafana:
environment:
# SMTP-Settings
- GF_SMTP_ENABLED=true
- GF_SMTP_HOST=smtp.gmail.com:587
- GF_SMTP_USER=your-email@gmail.com
- GF_SMTP_PASSWORD=app-password-hier
- GF_SMTP_FROM_ADDRESS=monitoring@wolfcoder.de
- GF_SMTP_FROM_NAME=WolfCoder Monitoring
# Contact Point in Grafana UI:
# Type: Email
# Addresses: admin@wolfcoder.de, team@company.com
# Subject: [{{ .Status }}] {{ .GroupLabels.alertname }}
# Message: Server {{ .GroupLabels.host }} needs attention!🎯 Zusammenfassung: Dein professionelles Monitoring-System läuft!
Du hast jetzt: Ein professionelles Monitoring-System, das echte Probleme erkennt, bevor sie kritisch werden. Nicht nur bunte Dashboards, sondern ein robustes System mit erweiterten Funktionen und detaillierten Troubleshooting-Lösungen.
✅ Was funktioniert
- TIG-Stack läuft stabil in Docker
- System- und Container-Metriken werden gesammelt
- Grafana zeigt übersichtliche, optimierte Dashboards
- Intelligente Alerts warnen vor echten Problemen
- Detaillierte Troubleshooting-Lösungen für 8 häufige Probleme
- Multi-Server-Monitoring möglich
- Custom Metriken und erweiterte Benachrichtigungen
- Backup-Strategie implementiert
🚀 Erweiterte Möglichkeiten
- Multi-Server-Setup für zentrale Überwachung
- Custom Metriken (HTTP-Endpoints, Datenbanken, Logs)
- Discord/Slack/E-Mail-Benachrichtigungen konfiguriert
- Memory-Optimierung und Performance-Tuning
- Automatische Backups und Recovery-Strategien
- Dashboard-Optimierung für bessere Performance
- Alert-Tuning gegen Spam und False-Positives
- Container-Monitoring mit Labels und Metadata
💡 Was dieser Guide anders macht
Statt „installiere diese 10 Tools“ zeige ich dir, warum jede Entscheidung Sinn macht,welche Probleme in der Praxis auftreten, und wie du sie löst. Basierend auf 5 Jahren echten Monitoring-Erfahrungen, nicht nur Lab-Setups.
Fragen? Probleme? Diskutiere auf dem Discord oder schau dir weitere Guides an.