Rotation von stdout protokollieren?

31774
Miral

Ich habe ein Linux-Programm, das Informationen zu stdout und stderr schreiben kann.

Ich habe ein Shell-Skript, das diese Ausgabe in eine Datei umleitet /var/log. (Via >>und 2>&1.)

Gibt es eine Möglichkeit, die Protokolldatei in Rotation zu versetzen? (maximale Größe, dann zu einer anderen Datei wechseln, nur eine begrenzte Anzahl von Dateien aufbewahren)

Ich habe einige Antworten gesehen, die über das logrotateProgramm sprechen, was sich gut anhört, aber sie scheinen sich auch auf Programme zu konzentrieren, die intern Protokolldateien generieren und HUP-Signale verarbeiten. Gibt es eine Möglichkeit, dies mit einem einfachen Skript für die Ausgabeumleitung zu erreichen?

43
Warum können Sie das Skript, mit dem die Ausgabe umgeleitet wird, nicht einfach so ändern, dass sie die Logik für die Rotation enthält? MaQleod vor 13 Jahren 1
Ich könnte, wenn mir jemand sagen könnte, wie ich die Größe eines Logfiles ermitteln und unter dem Standard eines Prozesses heraus drehen kann, ohne diesen Prozess zu stören. Ich muss * logrotate * nicht verwenden, wenn es eine bessere Option gibt, die sich wie ein bequemer Ausgangspunkt für Diskussionen anhört. Miral vor 13 Jahren 0
Sie müssen kein Logrotate verwenden, aber die Verwendung von Logrotate spart nur Zeit ... Es gibt normalerweise wenig Sinn, das Rad neu zu erfinden. bubu vor 13 Jahren 1
Genau mein Standpunkt. Gibt es eine Möglichkeit, logrotate mit einem umgeleiteten stdout eines laufenden Prozesses zu arbeiten? Miral vor 13 Jahren 0

9 Antworten auf die Frage

34
JdeBP

Als Alternative können Sie die Ausgabe über Tools weiterleiten, die vorrangig dazu dienen, Protokolldateisätze mit begrenzter, automatisch gedrehter Datei zu verwalten, z.

Zu den Tools für die Verarbeitung der multilogProtokolldateisätze gehören unter anderem:

Lesen Sie weiter

Danke, "Multilog" sieht genau so aus, wie ich es brauchte. Miral vor 13 Jahren 0
Multilog scheint die einzige Plug & Play-Lösung in Debian zu sein (daemontools hat ein offizielles Paket). In meinem speziellen Fall, wo ich die Protokolle auf einer fat32-Partition speichern wollte, funktioniert das Drehen nicht, da Multilog einen Symlink verwenden möchte. Kein Plug and Play für mich :) Arnout vor 6 Jahren 0
Das kann nicht wahr sein, da "multilog" nirgends symbolische Links schafft oder fordert. Es ist völlig neutral in Bezug auf sie. JdeBP vor 6 Jahren 0
15
BertNase

Das rotatelogsmit apache (im bindir) gelieferte tool (siehe docs ) nimmt die eingaben von stdin und dreht das Protokoll nach einiger zeit

14
Lara Dougan

Wenn Sie es zu einem der Standardprotokollströme (Syslog, Daemon, Cron, Benutzer, Sicherheit, E-Mail usw.) führen können logger, können Sie stattdessen den Befehl und die Pipe dorthin verwenden.

echo "Hello." | logger -p daemon.info 

Andernfalls können Sie den protokollierten Inhalt besser an ein benutzerdefiniertes Programm oder Skript übergeben, um ihn zu bearbeiten, oder die logrotateKonfiguration einrichten.

EDIT: JdeBPs Antwort scheint das zu haben, wonach Sie suchen.

+1 zur Vereinfachung. Übrigens können Sie auch eine benutzerdefinierte Einrichtung (local0) anstelle der Standardeinrichtung (Daemon in Ihrem Beispiel) konfigurieren. Roger Keays vor 12 Jahren 2
13
Sam Hendley

Ich hatte ein ähnliches Problem und hatte anfangs Logrotate verworfen, aber es stellte sich heraus, dass Logrotate dies tatsächlich gut kann. Die Schlüsseldirektive lautet " copytruncate ". Aus irgendeinem Grund kam dieser Begriff bei keinem der googeln auf, die ich gemacht habe. Deshalb füge ich diese Antwort hinzu, um zu präzisieren, wie er in diesem Fall verwendet werden kann.

Der Trick ist, dass dies nur funktioniert, wenn die Weiterleitung mit " >> " (Anhängen) anstelle von " > " (Erstellen) erfolgt.

Konfigurationsdatei (truncate.cfg):

/tmp/temp.log { size 10M copytruncate rotate 4 maxage 100 } 

Testprogramm (gibt die Datei niemals auf). Sie können die Füllung des Datenträgers verfolgen und obwohl das Löschen der Protokolldatei zu funktionieren scheint, wird tatsächlich kein Speicherplatz auf dem Datenträger freigegeben:

cat /dev/urandom >> /tmp/temp.log 

Laufprotokoll drehen:

logrotate truncate.cfg 
Es ist eine schöne Theorie, aber es funktioniert auf keinem System, auf dem ich es probiert habe. Die Datei wird nicht wirklich abgeschnitten und das Programm wird wie zuvor angefügt. (Und ja, das geht sogar mit der Umleitung über >>.) ((Übrigens, diese Antwort wurde bereits zuvor gegeben.)) Miral vor 10 Jahren 0
… Wie in [logrotate wird die Originaldatei nicht abgeschnitten] (http://unix.stackexchange.com/q/117852/80216) (auf unserer Unix- und Linux-Site) erläutert. Außerdem schreibt `echo / dev / urandom >> / tmp / temp.log` 13 deterministische Zeichen in` / tmp / temp.log` und beendet sich sofort. Meinten Sie „cat / dev / urandom“? G-Man vor 10 Jahren 1
Nur hier getestet, und es scheint zu funktionieren. Der Inhalt der Datei wird in die neue Protokolldatei kopiert. Die Originaldatei wird vom Prozess geöffnet gehalten und abgeschnitten (Größe zeigt jetzt 0). Philipp vor 9 Jahren 2
Festes Beispiel, danke G-Man Sam Hendley vor 8 Jahren 0
Seien Sie vorsichtig mit dem möglichen Datenverlust mit copytruncate. wanghq vor 8 Jahren 1
+1 obwohl "Beachten Sie, dass zwischen dem Kopieren und dem Abschneiden der Datei eine sehr kurze Zeitspanne liegt. Daher gehen möglicherweise einige Protokolldaten verloren." Tagar vor 7 Jahren 1
3
natevw

Gibt es eine Möglichkeit, logrotate mit einem umgeleiteten stdout eines laufenden Prozesses zu arbeiten?

Ja! Schauen Sie sich die von logrotate angebotene Direktive "copytruncate" an. Durch Angabe dieser Option wird logrotate angewiesen, genau mit dieser Situation umzugehen: Ein einfaches Programm, das seine Protokolldatei unbegrenzt geöffnet hält.

Ein Vorbehalt kann in Ihrer Situation ein Problem sein oder nicht:

Beachten Sie, dass zwischen dem Kopieren und dem Abschneiden der Datei eine sehr kurze Zeitspanne liegt, sodass einige Protokolldaten verloren gehen können.

Anekdotisch habe ich einige "echte" Protokollquellen gesehen, die Benutzer dazu ermutigen, diese Direktive anzuwenden. Es gibt einige Diskussionen über diese Option hier .

3
Nazar

Verwenden Sie split, es ist Teil von coreutils. Es kann stdin nehmen und es in Blöcke aufteilen (basierend auf der Blockgröße oder der Zeilenanzahl usw.).

Beispiel:

app | split --bytes 1G - /var/logs/put-prefix-here 

Hinweis dash (-) weist "split" an, stdin anstelle von Datei zu verwenden.

Können Sie Ihre Antwort erweitern, um zu beschreiben, wie das geht? Vielen Dank. fixer1234 vor 9 Jahren 0
habe gerade meine Antwort mit Beispiel aktualisiert. Nazar vor 9 Jahren 0
Die 1G ist eine beliebige Größe, nach der eine neue Datei gestartet wird? fixer1234 vor 9 Jahren 0
Dies ist keine besonders gute Lösung für das Problem, da Sie mit einer halben Nachricht in einer Datei und einer in der nächsten Datei arbeiten können. Es besteht auch das Risiko eines Datenverlusts, wenn die Maschine abstürzt, während "split" Daten in einem möglicherweise großen Puffer enthält. In Anbetracht der Tatsache, dass es mehrere Tools gibt, die dieses Problem richtig lösen, glaube ich nicht, dass diese Art der Roll-Your-Own-Lösung überhaupt empfohlen werden kann. David Richerby vor 9 Jahren 1
Alle Werkzeuge haben ihre Verwendung. Ich glaube nicht, dass alles, was mit Pipes funktioniert, keinen Datenverlust "garantiert". Dies ist eine schnelle und schmutzige Lösung, die bei vielen Jobs gut funktionieren würde. "Teilen" hat auch die Möglichkeit, die Anzahl der Zeilen (anstelle der Anzahl der Bytes) aufzuteilen. Es ist ein gutes altes Unix-Tool, das meiner Meinung nach immer noch verwendet wird. Nazar vor 9 Jahren 0
@ David Richerby: Wie wäre es, -u für ungepuffert hinzuzufügen? Nick vor 8 Jahren 1
2
sage

Ich mag es multilogfür meinen Anwendungsfall, aber mein Anwendungsfall ist so trivial / einfach, dass er nicht sehr einfach in den Dokumenten / Beispielen dargestellt ist, die ich gefunden habe. Hier ist ein einfaches Multilog-Beispiel:

mkdir /tmp/myapp ./myapp | multilog t s10000 n5 '!tai64nlocal' /tmp/myapp 2>&1 

Einige Notizen:

  • Diese Dumps werden in das Verzeichnis / tmp / myapp / geschrieben
  • Der s10000 steht für 10.000 Bytes *
  • Das n5 stellt 5 Dateien dar. * Das 'aktuelle' Protokoll zählt als eine der Dateien, daher umfasst es 4 ältere Protokolle + 'aktuell'.
  • Dies basiert auf den von François Beausoleil bereitgestellten Beispielen: http://blog.teksol.info/pages/daemontools/best-practices
  • Ich verstehe viele Optionen nicht - ich verweise Sie auf die verschiedenen Dokumentationen, um dies zu erweitern ...
  • Die Dokumente warnen, dass: "Note that running processor may block any program feeding input to multilog.""Prozessor" der '!tai64nlocal'Teil des Befehls ist

* Für viele Anwendungen sind diese Optionen für den Langzeitgebrauch schlecht. Sie ermöglichen es Ihnen, das Verhalten beim Füllen und Drehen der Protokolle schneller zu beobachten, als dies bei großen Protokollen der Fall ist.

Vergessen Sie nicht zu vergessen, wenn nötig! Mit nohup brauchen Sie nicht das 2>&1(s = 10e6 und n = 30 hier):

mkdir -p /tmp/myapp nohup ./myapp | multilog t s10000000 n30 '!tai64nlocal' /tmp/myapp & 

Dieser Befehl sollte Ihnen den Einstieg erleichtern.

1
user578558

Ich wollte nur Sam Hendleys Kommentar oben hinzufügen:

Der Trick ist, dass dies nur funktioniert, wenn die Weiterleitung mit >>(Anhängen) anstelle von >(Erstellen) durchgeführt wird.

Ich bin auf das gleiche Problem gestoßen, bei dem die Originaldatei immer größer wird, wenn Sie >(Erstellen) verwenden, aber wenn Sie >>(Anhängen) verwenden. Logrotate copytruncate funktioniert einwandfrei und wie erwartet. Die Originaldatei geht auf null Byte zurück und das Programm schreibt weiter.

Leiten Sie STDOUT und STDERR in eine rotierende Protokolldatei um:

  1. some-program.sh >> /tmp/output.txt 2>&1 &
  2. Erstellen Sie eine logrotate-Konfigurationsdatei /etc/logrotate.d, die in meinem Fall auch mit dem Namen "output_roll" bezeichnet wird.

    Beispielkonfiguration für meinen Fall:

    /tmp/output.txt { notifempty missingok size 1G copytruncate start 0 rotate 15 compress } 
  3. Richten Sie Ihren Cron-Job in der /etc/crontabDatei ein

    * * * * * root /usr/sbin/logrotate /etc/logrotate.d/output_roll 

    Dadurch wird die Datei jede Minute überprüft. Sie können sich an Ihre Bedürfnisse anpassen.

  4. Fang an:

    $> service crond restart 
  5. Das ist es

Hinweis: Ich hatte auch ein Problem mit der Einstellung von SELinux, SELINUX=enforcingalso habe ich es eingestellt SELINUX=disabled.

1
Victor Sergienko

I wrote a logrotee this weekend. I probably wouldn't if I've read @JdeBP's great answer and multilog.

I focused on it being lightweight and being able to bzip2 its output chunks like:

verbosecommand | logrotee \ --compress "bzip2 {}" --compress-suffix .bz2 \ /var/log/verbosecommand.log 

There's a lot of to be done and tested yet, though.