Vorab: Beides hat seine Daseinsberechtigung und Einsatzzwecke. Man wählt sein Werkzeug und die Methode nach dem zu erreichenden Ziel. Und man kann sie sinnvoll kombinieren.
| rsyslog | Loki/Grafana Alloy | |
|---|---|---|
| Primärer Fokus | System-Logs (Syslog) | Metriken/Logs/Traces/Profiles |
| Integration | Universell / Datei / Remote | Grafana/LokiStack |
| Ressourcen | Sehr gering (C-basiert) | Moderat (Go-basiert) |
| Konfiguration | Traditionelles Format | Pipelines (Alloy Syntax) |
| Kompatibilität | RFC 3164 / 5424 | RFC 5424 (Standard) OTLP |
Wenn die Aufgabe lautet "Finde rasch heraus, warum ein System abstürzt!" ist das eine Frage nach der Forensik.
Hier wählst du nicht den direkten Loki Alloy Ansatz, um möglichst viel zusätzliche Diagnose-Software auf diesem zu überwachenden System selbst zu ergänzen. Deine Metriken, etc. erstellst, sammelst und prozessierst du also möglichst nicht insystem, sondern außerhalb. Dies ist eine Grundlage der forensischen Analyse.
Du sorgst dafür, dass du relevante Informationen und Rohdaten möglichst einfach, unverändert und möglichst zeitnah zu deinem separaten Protokollsystem pushen kannst, ohne zusätzliche andere Abhängigkeiten im Userspace aufzubauen, die dieses Vorhaben wieder behindern könnten und das zu messende System selbst wiederum stark beeinflussen.
Du versuchst also auch den Ressourcenbedarf für das Protokollieren dieser Informationen möglichst gering zu halten. Für dieses Szenario ist daher rsyslog oft besser geeignet und du erhöhst einfach den loglevel betreffender Dienste für debug log. Dafür erhältst du die Daten aber auch unabhängig vom System und auch dann noch, wenn auf dem System der Arbeitsspeicher aufgebraucht ist, oder andere Prozesse der Verarbeitung einfrieren.
Konkret: In einem Forensik- oder Hardening-Szenario, bei dem es um Systemstabilität und Absturzursachen geht, ist rsyslog die fachlich richtige Wahl.
Es greifen dabei drei entscheidende Prinzipien der Systemadministration:
Wenn es brennt, willst du die einfachste und schnellste Möglichkeit, um die Daten vom brennenden Haus wegzuleiten. rsyslog fungiert hier als dieses Rohr. Grafana Alloy (oder ähnliche) setzt man eher als zentralen Relay-Server (Collector) ein, der die rsyslog-Datenströme von vielen Servern annimmt, filtert, mit Labels versieht und dann sauber in Loki speichert.
Erstelle eine neue Datei, z.B. /etc/rsyslog.d/10-remote-crashlog.conf mit diesem Inhalt:
# Alles an den zentralen Log-Server senden # hier im fiktiven Beispiel 192.168.1.111 # Verwende TCP (@@) für Zuverlässigkeit # oder UDP (@) für minimalen Overhead *.* @@192.168.1.111:514
Wichtig jedoch: Erzwinge das Schreiben/Senden ohne Verzögerung!
$ActionQueueType Direct $ActionResumeRetryCount -1 $ActionQueueSaveOnShutdown on
*.*Schickt absolut alles (alle Kontexte, alle Prioritäten) raus. Wenn du Debug-Logs aktiviert hast, landen sie hier.
@@ (TCP)Im Gegensatz zu UDP kann TCP sicherstellen, dass Pakete ankommen. Bei einem Systemfreeze versucht rsyslog so lange wie möglich, die Verbindung offen zu halten. ABER ACHTUNG!: Wenn der Zielserver weg ist, kann TCP bei Standardeinstellungen Prozesse blockieren! Wenn das System extrem instabil ist, ist hingegen @ (UDP) "feuerfester", da rsyslog die Pakete einfach blind abschickt. Wähle also weise! Beides hat vor und Nachteile! Meistens ist UDP hier die bessere Wahl und der beste Kompromiss. Nutze also nicht @@ sondern @
$ActionQueueType DirectDas ist hier der relevante Punkt. Es gibt dann keine Warteschlange im Arbeitsspeicher. Jede Logzeile wird sofort verarbeitet und gesendet. Wenn der RAM voll läuft, belegt rsyslog keinen zusätzlichen Platz für Logs. Für das Forensik Szenario ist das zwingend zu setzen.
Wenn auch Crypto relevant ist und du leider kein dediziertes Netzwerk zum unverschlüsselten direkten Protokollieren verwenden kannst oder darfst, so nutze dafür z.B. wireguard Tunnel im Kernel. UDP durch UDP.
Im Kernel ist es ebenso robust und auch dann verfügbar, wenn der Userspace Probleme macht. Dennoch hast du deine gepushten logs geschützt und transportverschlüsselt zugestellt, da wireguard im Kernelmode arbeitet.
Du hast damit eine gekapselte, verschlüsselte Standleitung, die so tief im Betriebssystem verankert ist, dass sie fast die Robustheit einer seriellen Konsole erreicht, aber über das Netzwerk skaliert. Selbst wenn systemd oder die Shell nicht mehr reagieren, triggert ein Kernel-Event oft noch einen letzten Log-Eintrag, den WireGuard dann noch nach draußen reicht.
Tipp: Du kannst mehrere Zielserver angeben und damit zu mehreren Servern parallel pushen. Das erhöht die Redundanz, falls dein Protokollserver einmal nicht verfügbar ist. Auch kannst du dabei unterschiedliche Routen und Netzwerkkarten verwenden.
# Alles via UDP an beide zentralen Log-Server senden # hier im fiktiven Beispiel 192.168.1.111 und 192.168.2.222 *.* @192.168.1.111:514 *.* @192.168.2.222:514
Damit die Daten in Loki landen, muss dein Alloy-Collector auf der "sicheren Seite" so konfiguriert sein, dass er rsyslog-Daten annimmt:
loki.source.syslog "rsyslog_receiver" {
listener {
address = "0.0.0.0:514"
protocol = "tcp"
labels = { job = "syslog-crash-watch" }
}
forward_to = [loki.write.local.receiver]
}
ABER! Aber auch hier verlässt du dich jetzt auf der empfangenden Seite mit Loki auf ein wackeliges Pferd!
Es gibt einen besseren Weg. Denke auch hier an Redundanz! Oft ist ein aufnehmender socklog oder rsyslog die sinnvollere Variante. Lieber zwei server über UDP angebunden über unterschiedliche routen. und die schreiben die Daten nur weg.
Wenn das Ziel also auch Ausfallsicherheit für Forensik ist, ist Grafana Loki (oder Alloy) als direkter Endpunkt nicht das geeignete Mittel der Wahl. Ein Datenbank-Indizierungsprozess oder eine komplexe Go-Laufzeit kann unter Last oder bei Netzwerk-Spikes hängen bleiben.
In einem Hochverfügbarkeits-Szenario für Crash-Analysen ist daher ein Ansatz mit socklog oder rsyslog als reiner Dump-Empfänger klar überlegen:
Anstatt die Logs direkt in eine Datenbank (Loki) zu pressen, nutzt du zwei einfache rsyslog Empfänger-Nodes:
Du sendest per rsyslog vom Quellsystem an zwei unterschiedliche IP-Adressen (idealerweise sogar über zwei verschiedene Netzwerkinterfaces/Routen) wie oben beschrieben.
UDP ist hier Trumpf. Der sendende Server feuert die Pakete einfach ab. Es gibt keinen TCP-Handshake, der den sterbenden Kernel blockieren könnte, falls der Empfänger langsam reagiert.
Auf der Empfängerseite macht rsyslog/socklog nichts weiter, als den Stream in eine Flatfile (Textdatei) auf die Disk zu schreiben. Das ist minimales Processing.
Warum? Das Schreiben in eine Datei ist eine der stabilsten Operationen im Betriebssystem. Keine Datenbank-Locks, kein RAM-Indexing.
Hierzu eine Konfiguration auf dem Empfänger im Beispiel als rsyslog.
# UDP Empfang aktivieren module(load="imudp") input(type="imudp" port="514") # Logs einfach nach Hostname/Datum in Dateien schreiben $template RemoteLogs,"/var/log/remote/%HOSTNAME%/%$YEAR%%$MONTH%% $DAY%.log" *.* ?RemoteLogs
Wenn du automatische und sichere atomare Rotation der Entries brauchst, nutze socklog, statt rsyslog auf der Empfängerseite. Siehe mein Tutorial 0bc1e96d458b
Loki kommt erst danach ins Spiel. Sobald die Daten sicher als Textdatei auf dem stabilen Log-Server liegen, kann ein lokaler Grafana Alloy oder Promtail diese Dateien in aller Ruhe auslesen ("tailing") und nach Loki schieben.
Du kannst (und solltest dazu) vorher die Einträge beider logserver Einträge im Stream mergen, bevor du sie durch Loki und Grafana nachprozessierst.
Der Vorteil ist klar ersichtlich: Wenn Loki Schluckauf hat oder das Netzwerk zum zentralen Monitoring hakt, liegen die Rohdaten immer noch sicher als Textdatei auf deinen redundanten Empfängern und du kannst jederzeit nachprozessieren.