Warum zentrales Logging: Das Problem, das Fluentd löst
Was schiefgeht, wenn Logs in Dutzenden Dateien und Formaten leben, und wie Fluentds Pipeline aus Sammeln, Transformieren und Senden das behebt.
Eine einzelne Anwendung, die in eine Logdatei schreibt, ist leicht zu lesen. Ein echtes System – mehrere Services, eine Datenbank, ein Message Broker, ein Ingress-Proxy, jeweils in eigenem Format an eigenem Ort loggend – ist es nicht. Diese Anleitung behandelt, warum das im großen Maßstab zu einem echten Problem wird, und das Pipeline-Modell, mit dem Fluentd es behebt.
Wofür Logs eigentlich da sind
Logs sind nicht nur ein nachträglicher Debugging-Gedanke. Dieselben Logdaten dienen typischerweise mehreren verschiedenen Zwecken zugleich:
- Debugging: nachvollziehen, was rund um den Zeitpunkt eines Fehlers passiert ist.
- Sicherheit: verdächtige Aktivität erkennen, etwa wiederholte fehlgeschlagene Anmeldungen von einer Adresse, die sich nur durch Korrelation von Ereignissen über Zeit oder Quellen zeigt.
- Compliance: Manche Branchen verlangen, bestimmte Aufzeichnungen für einen festgelegten Zeitraum aufzubewahren.
- Auditing: im Nachhinein beantworten, „wer hat wann worauf zugegriffen“.
Jeder davon braucht die Daten an einem Ort, durchsuchbar, nicht verstreut über einzelne Maschinen.
Wo naives Logging zusammenbricht
Zwei übliche Ausgangspunkte laufen beide gegen dieselbe Wand, wenn ein System wächst:
In lokale Dateien schreiben. Einfach und genau so, wie die meiste Software standardmäßig loggt, aber eine rohe Textdatei ist nicht für Analyse gebaut. Zeitstempel über die Logdateien von fünf verschiedenen Anwendungen in jeweils anderem Format zu vergleichen, um den Weg einer Anfrage durch ein System zu rekonstruieren, ist bestenfalls mühsam und von Hand oft unpraktikabel.
Direkt in eine Datenbank loggen. Sende alles direkt an Elasticsearch oder einen ähnlichen Speicher, und nun braucht jede Anwendung ihre eigene Client-Bibliothek, ihr eigenes Verbindungsmanagement und ihre eigene Einigung auf Felder und Formate. Jeder Entwickler löst effektiv dasselbe Integrationsproblem neu, und nichts garantiert, dass sie es zweimal auf dieselbe Weise lösen.
Keiner der Ansätze behandelt Drittkomponenten, deren Code du nicht kontrollierst – eine Datenbank, einen Message Broker, einen Ingress-Controller oder einfache Systemlogs, die Logs in dem Format erzeugen, mit dem sie gebaut wurden, nicht in dem, auf das sich deine eigenen Anwendungen geeinigt haben.
Das Pipeline-Modell: sammeln, transformieren, senden
Fluentds Ansatz ist, als eigene Schicht zwischen dem Ort, an dem Logs entstehen, und dem Ort, an dem sie landen, zu sitzen, aufgebaut als Pipeline mit drei Stufen:
Quellen Fluentd Ziele
┌─────────────┐ ┌───────────────────┐ ┌──────────────────┐
│ App-Logs │ │ │ │ Elasticsearch │
│ System-Logs │ ───────▶ │ sammeln → parsen │ ───────▶ │ S3 │
│ Container- │ │ → filtern/ │ │ Kafka │
│ stdout │ │ anreichern │ │ eine DB usw. │
└─────────────┘ └───────────────────┘ └──────────────────┘
Fluentd sammelt Logs von dort, wo sie entstehen, unabhängig von Quelle oder ursprünglichem Format. Es parst und transformiert sie in eine einheitliche Struktur und verwandelt unstrukturierten Text in Schlüssel-Wert-Daten. Dabei kann es Einträge mit nützlichem Kontext anreichern (welcher Pod, welcher Host, welcher Container hat diese Zeile erzeugt) oder sie filtern, indem es verwirft, was nicht gebraucht wird, oder sensible Felder schwärzt. Schließlich sendet es das Ergebnis an ein oder mehrere Ziele – eine Analyseplattform, einen Datenspeicher, Cold Storage –, ohne dass jede vorgelagerte Anwendung wissen oder sich darum kümmern muss, wo ihre Logs letztlich landen.
Tags: wie Fluentd Daten durch die Pipeline routet
Jeder Log-Eintrag, den Fluentd sammelt, bekommt einen Tag, einen String, den du beim Konfigurieren zuweist und der angibt, woher der Eintrag kam. Tags nutzen spätere Stufen der Pipeline, um zu entscheiden, was worauf angewendet wird: „Einträge mit Tag apache.access mit dem Apache-Logformat parsen“, „Einträge mit Tag app.* filtern, um ein Feld zu entfernen“, „Einträge mit Tag *.errors an dieses Ziel und alles andere an jenes senden“. Die Einzelheiten, diese Konfiguration zu schreiben, sind die nächste Anleitung dieser Reihe; hier zählt das Konzept: Ein Tag ist der Faden, der ein Datenstück mit der Quelle verbindet, aus der es kam, bis hin zu dem Ort, an den es schließlich gesendet wird.
Warum das eine eigene Schicht wert ist
Die Alternative zu einer solchen Pipeline ist nicht „keine Arbeit“, sondern dieselbe Parsing-, Anreicherungs- und Routing-Logik, in jeder Anwendung, die irgendetwas loggt, neu implementiert – uneinheitlich, jede ein wenig anders. Sie in einer konfigurierbaren Schicht zu zentralisieren bedeutet, dass diese Logik einmal geschrieben wird, und jede neue Anwendung nur Logs in dem Format erzeugen muss, das für sie am einfachsten ist – Klartext, JSON, was auch immer ein Drittwerkzeug schon schreibt –, und Fluentd sorgt ab dort für Konsistenz.
Beliebte Anleitungen
-
Grundlagen der Fluentd-Konfiguration: Source, Filter, Match und Tags Die Direktiven, aus denen jede Fluentd-Konfiguration besteht, wie Tags sie verbinden und wie du eine Konfiguration vor dem Start validierst. -
Logs aus Dateien, HTTP und Containern sammeln Konfiguriere die drei häufigsten Eingabequellen: eine Datei auf der Platte, einen HTTP-Endpunkt und jeden Container auf einem Docker-Host. -
Logs zuverlässig senden: Output-Plugins und Buffering Installiere ein Output-Plugin, route verschiedene Quellen zu verschiedenen Zielen und konfiguriere Buffering, damit ein ausgefallenes Backend keine Daten verliert.