Monitoring & Observability – Warum Logs allein nicht reichen
Hook: Stellen Sie sich vor, Sie beobachten ein Fußballspiel nur über das Ergebnis‑Board. Sie wissen, wer gewonnen hat, aber nichts über die Spielzüge, Taktiken oder Fehlpässe. Genau so fühlt sich ein klassisches Log‑Only‑Ansatz an – er zeigt Ihnen, dass etwas schiefgelaufen ist, aber nicht warum. In einer micro‑service‑basierten, containerisierten Welt ist das ein fataler Wissensverlust. In diesem Artikel zeige ich Ihnen, warum Sie Logs, Metrics und Traces kombinieren müssen, gebe drei handfeste Beispiele mit echten Befehlen und Konfigurationen und beende das Ganze mit einer persönlichen Einschätzung, wo Sie heute anfangen sollten.
Warum reine Log‑Analyse heute versagt
Erklärung
Traditionell haben Administratoren ihre Systeme mit syslog, journalctl oder einem ELK‑Stack (Elasticsearch, Logstash, Kibana) überwacht. Das funktioniert noch, wenn Sie ein monolithisches Backend betreiben. Sobald jedoch asynchrone Grenzen zwischen Prozessen, Netzwerk‑Calls und Hintergrundjobs treten, verliert das reine Log‑Parsing an Aussagekraft. Logs sind zeitlich sortiert, aber nicht kausal verknüpft – Sie können nicht mehr verfolgen, welche Anfrage welche Datenbankabfrage auslöste.
Konkretes Beispiel 1 – Log‑Filterung mit journalctl
# Zeige alle Fehlermeldungen des nginx‑Service seit Systemstart
sudo journalctl -u nginx.service -p err --since "today"
Der Befehl liefert Ihnen Zeilen mit Fehlermeldungen, aber keine Herkunftsinformation, warum der Fehler auftrat. Sie sehen, dass 404 generiert wurden, aber nicht, ob ein fehlerhafter Client‑Header, ein DNS‑Timeout oder ein falsch konfigurierter Reverse‑Proxy die Ursache war.
Persönliche Einschätzung
Ich habe in mehreren Projekten die gleiche Situation erlebt: Das Team verließ sich auf Log‑Alarme, doch jedes Mal, wenn ein Incident auftrat, dauerte es Stunden, bis die eigentliche Ursache gefunden war. Der Grund: Logs geben nur Symptome, nie die Diagnose.
Grundlagen des Distributed Tracing
Erklärung
Tracing ergänzt Logs, indem es Spuren (spans) über Service‑Grenzen hinweg erstellt. Jeder Span bekommt eine eindeutige Trace‑ID und eine Parent‑ID, wodurch ein hierarchisches Bild entsteht: vom eingehenden HTTP‑Request bis zu den hinteren Datenbank‑Calls. Das Ergebnis ist ein zeitlich und kausal verknüpfter Ablaufplan.
Konkretes Beispiel 2 – OpenTelemetry‑Instrumentierung in Go
import (
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/trace"
"go.opentelemetry.io/otel/sdk/trace"
)
func main() {
exporter, _ := otlphttp.New(context.Background(), otlphttp.WithEndpoint("localhost:4318"))
tp := trace.NewTracerProvider(trace.WithSyncer(exporter))
otel.SetTracerProvider(tp)
tracer := otel.Tracer("example-service")
ctx, span := tracer.Start(context.Background(), "handleRequest")
defer span.End()
// ... Ihre Business‑Logik
_ = ctx
}
Durch dieses Minimalbeispiel wird für jede eingehende Anfrage ein Span erzeugt, der an den OpenTelemetry Collector (otelcol) gesendet wird. In Jaeger oder Grafana Tempo lässt sich dann die komplette Request‑Kette visualisieren.
Persönliche Einschätzung
Tracing ist kein Nice‑to‑Have, sondern ein Must‑Have in einer verteilten Architektur. Der Aufwand für die Grundinstrumentierung liegt meist unter 5 % des Entwicklungszeitplans, zahlt sich aber mit deutlich geringeren MTTR (Mean Time To Recovery) aus.
Praktische Implementierung mit OpenTelemetry, Jaeger und Loki
Erklärung
Ein gängiges Stack‑Muster kombiniert OpenTelemetry Collector (OTel Collector) als Aufnahmepunkt, Jaeger für Traces, Grafana Loki für Logs und Prometheus für Metriken. Der Collector kann Logs, Metrics und Traces simultan an ihre jeweiligen Backends weiterleiten.
Konkretes Beispiel 3 – OTel‑Collector‑Konfiguration (YAML)
receivers:
otlp:
protocols:
grpc:
http:
exporters:
jaeger:
endpoint: "jaeger:14250"
tls:
insecure: true
loki:
endpoint: "http://loki:3100/api/prom/push"
tls:
insecure_skip_verify: true
service:
pipelines:
traces:
receivers: [otlp]
exporters: [jaeger]
logs:
receivers: [otlp]
exporters: [loki]
Starten Sie den Collector mit Docker:
docker run --rm -p 4317:4317 -p 55681:55681 \
-v $(pwd)/otel-collector.yaml:/etc/otelcol/config.yaml \
otel/opentelemetry-collector:0.99.0
Jetzt fließen sämtliche Traces aus Ihren micro‑services in Jaeger, während parallele Log‑Einträge in Loki landen. Beide Systeme lassen sich im Grafana‑Dashboard nebeneinander darstellen – das ist Observability in Action.
Persönliche Einschätzung
Der größte Stolperstein beim Aufbau dieses Stacks ist die Konsistenz der Trace‑IDs zwischen Log‑ und Trace‑Systemen. Sobald Sie dafür sorgen, dass Ihre Log‑Bibliothek die aktuelle Trace‑ID in ein Feld wie trace_id schreibt (z. B. via logrus Hook), haben Sie den entscheidenden Baustein für log‑trace correlation.
Kombinieren von Logs, Metrics und Traces – Das 3‑teilige Observability‑Puzzle
Erklärung
Jedes Element liefert einen anderen Blickwinkel:
- Logs – detaillierte, textbasierte Ereignisse (z. B. Fehlermeldungen).
- Metrics – aggregierte Zahlenwerte, ideal für Schwellwert‑Alarme (CPU‑Auslastung, Request‑Rate).
- Traces – kausale Pfade, die zeigen, wie Anfragen durch das System wandern.
Durch die Korrelation dieser Daten können Sie Fragen wie „Warum ist die 5‑Minute‑Durchschnittslatenz plötzlich auf 300 ms gestiegen?“ beantworten, indem Sie den Trace‑Pfad zum betroffenen Service verfolgen und gleichzeitig die relevanten Log‑Einträge einblenden.
Konkretes Beispiel 4 – Correlation in Grafana Loki Query
# Suche alle Logs, die zu einer bestimmten Trace‑ID gehören
time range: now-5m to now
query: {job="frontend"} |~ "trace_id=\"00a1b2c3d4e5f6\""
Mit diesem Loki‑Query erscheinen exakt die Log‑Zeilen, die zu dem Trace 00a1b2c3d4e5f6 gehören. Öffnen Sie den zugehörigen Trace in Jaeger und Sie erhalten ein komplettes Bild – von der HTTP‑Anfrage bis zum Datenbank‑Timeout.
Persönliche Einschätzung
In meinen letzten Projekten hat die Korrelation von Log‑ und Trace‑ID die Fehlersuche von Stunden auf Minuten gesenkt. Das ist kein Nice‑to‑Have, das ist Kostensenkung – jede vermiedene Minute im Incident Management spart Geld.
Häufige Fehler beim Observability‑Aufbau
- Nur ein Tool verwenden – Einseitige Sicht (z. B. nur ELK) führt zu blinden Flecken.
-
Fehlende Trace‑IDs in Logs – Ohne
trace_idkönnen Sie Logs nicht zum Trace zurückführen. -
Zu hohe Retention – Logs werden unbegrenzt gespeichert, was Ressourcen verschlingt; setzen Sie
max_agein Loki. -
Mangelnde Sampling‑Strategie – Vollständiges Tracing aller Requests belastet das Netzwerk; nutzen Sie probabilistisches Sampling (
sampling_ratio: 0.1). - Unklare Verantwortlichkeiten – Teams denken, das Observability‑Team sei allein verantwortlich; in Wahrheit muss jede Service‑Entwicklung instrumentiert sein.
Persönliche Einschätzung
Der kritischste Fehler ist das „Observability‑Monolith“ – wenn nur ein Team das Monitoring verwaltet, entstehen Silos. Ich empfehle, Ownership pro Service zu etablieren: Jeder Service‑Owner sorgt für seine Instrumentierung, während ein zentrales SRE‑Team das Dashboard‑ und Alert‑Management übernimmt.
Fazit und der nächste konkrete Schritt
Logs allein geben Ihnen ein Symptom, Traces zeigen die Ursache. Kombinieren Sie beide mit Metriken, um ein vollständiges Bild Ihrer Infrastruktur zu erhalten. Der Aufwand für die Grundinstrumentierung ist überschaubar, und die meisten Open‑Source‑Tools (OpenTelemetry, Jaeger, Loki, Prometheus) bieten out‑of‑the‑box‑Integrationen.
Ihr nächster Schritt (Handlungsaufforderung)
- Installieren Sie den OpenTelemetry Collector – nutzen Sie das obige Docker‑Kommando.
- Instrumentieren Sie mindestens einen Service – kopieren Sie das Go‑Beispiel oder das entsprechende Java/Python‑Snippet.
-
Ergänzen Sie Ihre Log‑Bibliothek um die Trace‑ID – z. B. mit dem
logrusHooklogrus.AddHook(traceHook{}). - Erstellen Sie ein Grafana‑Dashboard mit einem Panel, das Traces und Logs nebeneinander anzeigt.
-
Setzen Sie ein erstes Alert‑Rule in Prometheus (z. B.
rate(http_requests_total[5m]) > 1000) und prüfen Sie, ob Sie über das ergänzte Trace‑Dashboard sofort den betroffenen Service identifizieren können.
Durch konsequente Umsetzung dieses 5‑Schritte‑Plans schließen Sie die Lücke zwischen reiner Log‑Analyse und echter Observability – und reduzieren Ihre MTTR von Stunden auf Minuten.
Bleiben Sie neugierig, experimentieren Sie mit Sampling‑Rates und behalten Sie immer das Ziel vor Augen: **Schnelle, kausale Erkenntnisse* statt endloser Log‑Durchsuchungen.*
Top comments (0)