Log Rotation von stdout?

53

Ich habe ein Linux-Programm, das Informationen in 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, diese Protokolldatei rotieren zu lassen? (maximale Größe, dann zu einer anderen Datei wechseln, nur eine begrenzte Anzahl von Dateien aufbewahren)

Ich habe ein paar 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 grundlegenden Ausgabeumleitungsskript zu erreichen?

Miral
quelle
1
Warum können Sie das Skript, das die Ausgabe umleitet, nicht einfach so ändern, dass es die Logik für die Drehung enthält?
MaQleod
Ich könnte, wenn jemand mir sagen könnte, wie man die Größe einer Protokolldatei erkennt und sie unter dem Standard eines Prozesses herausdreht, ohne diesen Prozess zu stören. Ich glaube nicht , haben zu verwenden , logrotatewenn es eine bessere Option, die wie ein bequemer Ausgangspunkt für die Diskussion nur klang.
Miral
2
Sie müssen nicht logrotate verwenden, aber logrotate spart nur Zeit ... Normalerweise macht es wenig Sinn, das Rad neu zu erfinden.
Bubu
Genau mein Standpunkt. Gibt es eine Möglichkeit, die Logrotation mit der umgeleiteten Standardausgabe eines laufenden Prozesses arbeiten zu lassen?
Miral

Antworten:

44

Alternativ können Sie die Ausgabe über Tools weiterleiten, die in erster Linie dazu dienen, Protokolldateigruppen mit Größenbeschränkung und automatischer Drehung zu verwalten, z.

Zu den Tools zum anschließenden Verarbeiten von multilogProtokolldateigruppen im Format gehören unter anderem:

Weitere Lektüre

JdeBP
quelle
1
Danke, multilogsieht aus wie genau das, was ich brauchte.
Miral
multilog scheint die einzige plug-and-play-lösung in debian zu sein (daemontools hat ein offizielles paket). Aber in meinem speziellen Fall, in dem 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
Das kann nicht wahr sein, da multilognirgendwo symbolische Verknüpfungen entstehen oder verlangt werden. Es ist ihnen gegenüber völlig neutral.
JdeBP
Die URL von "Verwende in diesem Jahrhundert kein Logrotate oder Newsyslog" hat einen zusätzlichen Punkt
duyue
15

Das rotatelogsmit Apache gelieferte Tool (im binVerzeichnis) (siehe Dokumentation ) nimmt Eingaben von stdin entgegen und dreht das Protokoll nach einer bestimmten Zeit

BertNase
quelle
14

Wenn Sie es zu einem der Standard-Protokolldatenströme (Syslog, Daemon, Cron, Benutzer, Sicherheit, E-Mail usw.) weiterleiten lassen können logger, können Sie stattdessen den Befehl verwenden und eine Pipe zu diesem Stream erstellen .

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

Andernfalls ist es möglicherweise besser, den protokollierten Inhalt an ein benutzerdefiniertes Programm oder Skript weiterzuleiten, um ihn zu verarbeiten, oder die logrotateKonfiguration einzurichten .

EDIT: Die Antwort von JdeBP scheint das zu haben, wonach Sie suchen.

Lara Dougan
quelle
2
+1 zur Vereinfachung. Übrigens können Sie auch eine benutzerdefinierte Einrichtung (local0) anstelle der Standardeinrichtungen (in Ihrem Beispiel Daemon) konfigurieren
Roger Keays
14

Ich hatte ein ähnliches Problem und musste anfänglich logrotate verwerfen, aber es stellte sich heraus, dass logrotate dies tatsächlich gut kann. Die Schlüsselanweisung ist " copytruncate ". Aus irgendeinem Grund tauchte dieser Begriff bei keinem der von mir durchgeführten Google-Vorgänge auf. Daher füge ich diese Antwort hinzu, um zu verdeutlichen, wie er in diesem Fall verwendet wird.

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

Konfigurationsdatei (truncate.cfg):

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

Testprogramm (gibt Datei nie auf). Sie können beobachten, wie der Datenträger gefüllt wird, und obwohl das Löschen der Protokolldatei funktioniert, wird tatsächlich kein Speicherplatz auf dem Datenträger freigegeben:

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

Laufendes Protokoll drehen:

logrotate truncate.cfg
Sam Hendley
quelle
Es ist eine schöne Theorie, aber sie funktioniert auf keinem System, auf dem ich sie ausprobiert habe. Die Datei wird nicht wirklich abgeschnitten, und das Programm hängt sie weiterhin wie zuvor an. (Und ja, das ist sogar mit der Umleitung über >>.) ((Übrigens, diese Antwort wurde bereits zuvor gegeben.))
Miral
1
… Wie in logrotate beschrieben, schneidet die Originaldatei nicht ab (auf unserer Unix- und Linux-Site). Außerdem echo /dev/urandom >> /tmp/temp.logwerden 13 deterministische Zeichen geschrieben /tmp/temp.logund sofort beendet. Meinten Sie cat /dev/urandom?
G-Man sagt, dass Monica
2
Gerade hier getestet, und es scheint zu funktionieren. Der Inhalt der Datei wird in eine neue Protokolldatei kopiert. Die Originaldatei wird vom Prozess geöffnet und abgeschnitten (Größe zeigt jetzt 0).
Philipp
1
Seien Sie vorsichtig mit dem möglichen Datenverlust bei copytruncate.
Wanghq
1
+1 obwohl "Beachten Sie, dass es eine sehr kurze Zeitspanne zwischen dem Kopieren und dem Abschneiden der Datei gibt, sodass möglicherweise einige Protokolldaten verloren gehen."
Tagar
3

Gibt es eine Möglichkeit, die Logrotation mit der umgeleiteten Standardausgabe eines laufenden Prozesses arbeiten zu lassen?

Ja! Schauen Sie sich die von logrotate angebotene Anweisung "copytruncate" an. Wenn Sie dies angeben, wird logrotate angewiesen, genau mit dieser Situation umzugehen: ein einfaches Programm, dessen Protokolldatei unbegrenzt geöffnet bleibt.

Eine Einschränkung kann in Ihrer Situation ein Problem sein oder auch nicht:

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

Anekdotisch habe ich einige "echte" Protokollquellen gesehen, die Benutzer dazu ermutigen, diese Direktive anzuwenden. Diese Option wird hier diskutiert .

natevw
quelle
3

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

Beispiel:

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

Beachten Sie, dass der Bindestrich (-) "split" anweist, stdin anstelle von file zu verwenden.

Nazar
quelle
Können Sie Ihre Antwort erweitern, um zu beschreiben, wie das geht? Vielen Dank.
fixer1234
habe gerade meine Antwort mit Beispiel aktualisiert.
Nazar
Die 1G ist eine beliebige Größe, nach der es eine neue Datei startet?
Fixer1234
1
Dies ist keine besonders gute Lösung für das Problem, da es bedeutet, dass Sie in einer Datei eine halbe und in der nächsten eine halbe Nachricht erhalten können. Es besteht auch die Gefahr eines Datenverlusts, wenn der Computer abstürzt, während splitsich Daten in einem möglicherweise großen Puffer befinden. Angesichts der Tatsache, dass es mehrere Tools gibt, die dieses Problem ordnungsgemäß lösen, kann diese Art der Eigenentwicklung meines Erachtens überhaupt nicht empfohlen werden.
David Richerby
1
@ David Richerby- wie wäre es, -u für ungepufferte hinzuzufügen?
Nick
3

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

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

Einige Notizen:

  • Dadurch werden die Protokolle in das Verzeichnis / tmp / myapp / kopiert
  • der s10000 repräsentiert 10.000 bytes *
  • Der n5 stellt 5 Dateien dar. * Das 'aktuelle' Protokoll zählt als eine der Dateien. Dies beinhaltet also 4 ältere Protokolle + 'aktuell'.
  • Dies basiert auf den Beispielen von François Beausoleil unter: http://blog.teksol.info/pages/daemontools/best-practices
  • Ich verstehe nicht viele der Optionen - ich verweise auf die verschiedenen Dokumentationen, um dies zu erweitern ...
  • In den Dokumenten wird Folgendes gewarnt: "Note that running processor may block any program feeding input to multilog."wobei "Prozessor" der '!tai64nlocal'Teil des Befehls ist

* Für viele Anwendungen ist dies eine schlechte Wahl für den Langzeitgebrauch. Mit ihnen können Sie das Befüllen und Drehen der Protokolle schneller beobachten als mit großen Protokollen.

Schließlich vergessen Sie nicht, bei Bedarf zu nohup! 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 &

Mit diesem Befehl können Sie loslegen.

Salbei
quelle
1

Ich wollte nur den obigen Kommentar von Sam Hendley ergänzen:

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

Ich bin auf dasselbe Problem gestoßen, bei dem die Originaldatei immer größer wird, wenn Sie Logrotate verwenden >(create), aber wenn Sie >>Logrotate verwenden (append), funktioniert copytruncate wunderbar und wie erwartet. Die ursprüngliche Datei wird auf null Byte zurückgesetzt 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 unter dem /etc/logrotate.dNamen "whatever", in meinem Fall "output_roll".

    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 damit, dass SELinux auf eingestellt war, SELINUX=enforcingalso habe ich es auf eingestellt SELINUX=disabled.

user578558
quelle
1

Ich habe an diesem Wochenende einen Logrotee geschrieben . Ich würde es wahrscheinlich nicht tun, wenn ich die großartige Antwort von @ JdeBP gelesen und gelesen hätte multilog.

Ich habe mich darauf konzentriert, dass es leichtgewichtig ist und in der Lage ist, seine Ausgabestücke wie folgt zu bzip2:

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

Es gibt jedoch noch viel zu tun und zu testen.

Victor Sergienko
quelle