Monitoring ist keine Kür

In Microservice-Architekturen ist Monitoring nicht optional, es ist Grundvoraussetzung für den Betrieb. Ein verteiltes System, das man nicht beobachten kann, ist ein System, das man nicht beherrscht. Diese Erfahrung haben wir in mehreren Projekten gemacht, sowohl bei unseren eigenen Produkten als auch in Enterprise-Umgebungen.

Der Begriff Observability fasst drei Säulen zusammen: Metriken, Logs und Traces. In diesem Artikel konzentrieren wir uns auf Metriken und Logs mit dem Stack aus Prometheus, Grafana und Loki.

Prometheus, Pull-basiertes Monitoring

Prometheus ist der De-facto-Standard für Metriken in Kubernetes-Umgebungen. Die Architektur unterscheidet sich fundamental von Push-basierten Systemen wie Graphite oder InfluxDB.

Architektur im Überblick

  • Prometheus Server scrapt Metriken von konfigurierten Endpoints in regelmäßigen Intervallen (Pull-Modell)
  • Exporters exponieren Metriken im Prometheus-Format über HTTP-Endpoints
  • Alertmanager verarbeitet und routet Alarme
  • Service Discovery in Kubernetes erkennt neue Pods automatisch über Annotations

Das Pull-Modell hat einen entscheidenden Vorteil: Prometheus kontrolliert, wann und wie oft Metriken abgerufen werden. Das verhindert, dass ein fehlerhafter Service den Monitoring-Stack mit Daten flutet.

Konfiguration für Spring Boot

Spring Boot Anwendungen exponieren Metriken über Micrometer und den Actuator-Endpoint. Die Integration ist minimal:

# application.yml
management:
  endpoints:
    web:
      exposure:
        include: prometheus, health, info
  metrics:
    tags:
      application: ${spring.application.name}
    export:
      prometheus:
        enabled: true

Kubernetes Service Discovery erfolgt über Pod-Annotations:

annotations:
  prometheus.io/scrape: "true"
  prometheus.io/port: "8080"
  prometheus.io/path: "/actuator/prometheus"

Wichtige Metriken für JVM-Anwendungen

Nicht jede Metrik ist gleich relevant. Für JVM-basierte Spring Boot Services haben sich folgende Metriken als unverzichtbar erwiesen:

MetrikBeschreibungWarum relevant
jvm_memory_used_bytesHeap- und Non-Heap-SpeicherMemory Leaks frühzeitig erkennen
jvm_gc_pause_secondsGarbage Collection PausenPerformance-Einbrüche identifizieren
http_server_requests_secondsRequest-Latenz und DurchsatzSLA-Überwachung
hikaricp_connections_activeAktive DB-ConnectionsConnection Pool Exhaustion verhindern
kafka_consumer_records_lagConsumer Lag bei KafkaVerarbeitungsrückstände erkennen

PromQL, Abfragesprache

Prometheus’ Stärke liegt in PromQL, einer mächtigen Abfragesprache für Zeitreihendaten. Einige Beispiele aus der täglichen Arbeit:

# Error Rate der letzten 5 Minuten
rate(http_server_requests_seconds_count{status=~"5.."}[5m])
/ rate(http_server_requests_seconds_count[5m])

# 95. Perzentil der Request-Latenz
histogram_quantile(0.95,
  rate(http_server_requests_seconds_bucket[5m])
)

# Kafka Consumer Lag über alle Partitionen
sum by (topic) (kafka_consumer_records_lag)

Grafana, Visualisierung und Dashboards

Grafana ist die Visualisierungsschicht. Dashboards sollten nicht beliebig sein, sondern einer klaren Hierarchie folgen:

Dashboard-Strategie

  • Overview Dashboard, Gesamtstatus aller Services auf einen Blick. Grün/Gelb/Rot. Hier schauen wir morgens als erstes drauf
  • Service Dashboard, Detailansicht pro Microservice: Latenz, Durchsatz, Error Rate, Ressourcenverbrauch
  • Infrastructure Dashboard, Kubernetes Cluster Health: Node-Auslastung, Pod-Status, Storage
  • Business Dashboard, Fachliche Metriken: Transaktionen pro Minute, Verarbeitungsdauer, Fehlerquoten nach Kategorie

Variablen und Templating

Grafana-Dashboards sollten parametrisiert sein. Mit Variablen kann ein einzelnes Dashboard für alle Environments und Services wiederverwendet werden:

  • $namespace, Kubernetes Namespace (dev, qa, prod)
  • $service, Service-Name
  • $interval, Scrape-Intervall für Rate-Berechnungen

Das reduziert die Anzahl der Dashboards drastisch und verhindert Dashboard-Wildwuchs.

Alerting, die richtige Strategie

Alerting ist der Bereich, in dem die meisten Teams Fehler machen. Zu viele Alerts führen zu Alert Fatigue, niemand reagiert mehr. Zu wenige bedeuten, dass Probleme unbemerkt bleiben.

Grundregeln für effektives Alerting

  • Alert auf Symptome, nicht auf Ursachen, Ein Alert “Error Rate > 5%” ist besser als “CPU > 80%”. Die CPU kann bei 90% sein und alles funktioniert. Die Error Rate zeigt, ob Nutzer betroffen sind
  • Severity-Stufen definieren, Critical (sofortige Reaktion nötig), Warning (Aktion innerhalb Stunden), Info (zur Kenntnis)
  • Runbooks verlinken, Jeder Alert muss eine Handlungsanweisung enthalten. Was soll der On-Call-Engineer tun?

Alertmanager-Routing

route:
  receiver: 'default'
  group_by: ['alertname', 'namespace']
  group_wait: 30s
  group_interval: 5m
  routes:
    - match:
        severity: critical
      receiver: 'pagerduty'
    - match:
        severity: warning
      receiver: 'slack-warnings'

Loki, Logs als Ergänzung

Metriken allein reichen nicht. Für die Ursachenanalyse braucht man Logs. Grafana Loki ist die logische Ergänzung zu Prometheus, es verwendet ein ähnliches Label-basiertes Konzept und integriert sich nahtlos in Grafana.

Vorteile gegenüber ELK-Stack

  • Geringerer Ressourcenverbrauch, Loki indiziert nur Labels, nicht den vollständigen Log-Text
  • Gleiche Label-Taxonomie wie Prometheus, Korrelation zwischen Metriken und Logs wird trivial
  • Promtail als Agent, Leichtgewichtiger Log-Shipper, der in Kubernetes als DaemonSet läuft

In der Praxis navigiert man in Grafana von einem auffälligen Metrik-Spike direkt zu den zugehörigen Logs, gleicher Zeitraum, gleicher Service, gleicher Pod. Diese Korrelation spart bei der Fehleranalyse erheblich Zeit.

Erfahrungen aus dem Betrieb

Einige Lektionen aus dem Betrieb unserer eigenen Produkte und Enterprise-Projekte:

  • Retention realistisch planen, 15 Tage Full Resolution, danach Downsampling auf Stundenwerte. Prometheus ist kein Langzeitarchiv
  • Recording Rules nutzen, Häufig abgefragte PromQL-Expressions als Recording Rules vorberechnen. Das beschleunigt Dashboards erheblich
  • Cardinality im Auge behalten, Jede Label-Kombination erzeugt eine eigene Zeitreihe. Unbegrenzte Labels (z.B. User-IDs als Label) sprengen den Speicher
  • Monitoring des Monitorings, Prometheus selbst muss überwacht werden. Ein zweiter Prometheus im Cross-Monitoring-Setup ist empfehlenswert

Fazit

Prometheus und Grafana bilden einen ausgereiften, produktionserprobten Stack für die Observability von Microservices. Die Investition in ein durchdachtes Monitoring-Setup zahlt sich bei jedem Incident aus, nicht als Nice-to-have, sondern als Voraussetzung für den verantwortungsvollen Betrieb verteilter Systeme.