Das Offensichtliche ist tail -f app.log db.log, aber in der Produktion lauert eine Falle: wenn logrotate die Datei dreht, benennt sie diese um und erstellt eine neue, -f behält den alten Dateideskriptor offen und du starrst auf einen eingefrorenen Bildschirm. Die Lösung ist ein Zeichen: -F öffnet die Datei nach Namen neu statt nach Inode. Hier ist, wann du welche Variante einsetzt.
1. Beide Dateien mit trennenden Headern anzeigen
$ clai zeige beide diese Logs gleichzeitig→ tail -n +1 app.log db.log==> app.log <==line A1==> db.log <==line B1
Wenn du mehrere Dateien gleichzeitig durchsuchst, gibt tail automatisch Header aus wie ==> Dateiname <==, um zu zeigen, welcher Quelle jede Zeile entstammt. Das ist entscheidend: ohne Header wirst du nicht wissen, aus welchem Log welche Zeile kommt.
2. Beide Logs in Echtzeit verfolgen
$ clai verfolge beide Logs während neue Zeilen ankommen→ tail -f app.log db.log
Der Header wird erneut ausgegeben, jedes Mal wenn die Quelle wechselt. Während eine Datei geschrieben wird, siehst du keinen Header; wenn die andere Datei eine Zeile erhält, erscheint der Header.
3. Die Log-Rotation überstehen und weiterlesenlesen
$ clai verfolge das Log, damit es nach der Rotation nicht verstummt→ tail -F /var/log/app/app.log
Das ist die Zeile, die zählt. -f hält den Dateideskriptor offen: nachdem logrotate die Datei umbenennt und eine neue erstellt, bleibt tail -f die umbenannte Kopie lesend und sieht nie neue Zeilen. -F beobachtet den Dateinamen und öffnet die Datei neu. Verwende auf der Produktionsumgebung immer -F.
4. Jede Zeile mit dem Quellnamen kennzeichnen
$ clai zeige beide Logs gemischt, aber kennzeichne jede Zeile mit dem Dateinamen→ for f in app.log db.log; do tail -F "$f" | sed "s/^/[$f] /" & done; wait
Block-Header werden unbequem, wenn Logs gleichzeitig geschrieben werden. Ein Präfix auf jeder Zeile ist leichter zu lesen. Das & startet jedes tail im Hintergrund, und wait hält die Shell am Laufen.
5. Alle Log-Dateien in einem Verzeichnis beobachten, einschließlich später erstellter
$ clai verfolge alle Log-Dateien im Verzeichnis→ tail -F /var/log/app/*.log
Die Shell erweitert das Glob einmal, beim Starten. Dateien, die später erstellt werden, werden nicht aufgenommen — du müsstest den Befehl neu starten.
6. Wenn du eine echte Oberfläche mit Panels brauchst
$ clai zeige mir mehrere Logs in separaten Panels→ multitail /var/log/syslog /var/log/auth.log
multitail zeichnet Panels mit Syntax-Hervorhebung und Filtern. Für Incident-Triage mit vier Logs auf einmal ist das deutlich besser als ein Stream. Installiere es separat.
Stolperfallen
-fund-Funterscheiden sich nur bei der Rotation. Bevor die Rotation stattfindet, gibt es keinen Unterschied, also wird die Gewohnheit,-fzu verwenden, nicht bestraft. Bestraft wirst du in dem Moment, in dem du auf eine Log-Zeile wartest und während eines Incidents kommt sie nicht mehr an.tail -füber das Netz funktioniert nicht gut. Auf NFS erreichen Änderungen möglicherweise nicht den Client. Sieh dir das Log auf der Maschine an, auf der es geschrieben wird.- Zeilen können sich vermischen. Zwei Prozesse, die in einen Stream schreiben, sind nicht synchronisiert. Um die Reihenfolge von Ereignissen zu verstehen, lese die Zeitstempel in den Zeilen, nicht die Ausgabereihenfolge.
Verwandte Fragen
Wie starte ich das Lesen ab einer bestimmten Zeile statt vom Ende? tail -n +100 file beginnt bei Zeile 100, tail -c +1000 beginnt bei Byte 1000.
Wie kann ich ein Log verfolgen und gleichzeitig filtern? tail -F app.log | grep --line-buffered ERROR. Ohne --line-buffered puffert grep die Ausgabe, und Zeilen kommen mit Verzögerung an.
Warum ist journalctl besser als tail für Dienste? Es versteht Rotation, kann nach Unit und Log-Level filtern, und hängt nicht davon ab, wohin der Dienst schreibt.
Siehe auch
- Read a service's logs with journalctl
- Sweep old logs and backups with one sentence
- Grep with exclusions
Höre auf, tail und logrotate Edge Cases auswendig zu lernen — beschreibe, was du sehen musst, und CliAI schreibt den Befehl. In einer Zeile installieren.