Frage Wie kann ich stdout weiter in eine Datei umleiten, nachdem logrotate es verschoben hat?


Ich habe ein einfaches Skript, das eine Reihe von Protokollen auf dem Bildschirm ausgibt, und ich piped die STDOUT in eine Datei, um die Protokolle zu speichern. Da dieses Skript lange läuft, musste ich die Protokolldateien so drehen, dass sie in kleinere, besser zu verwaltende Dateien umgewandelt werden.

Das Problem, mit dem ich konfrontiert war, war, dass einmal logrotate Verschiebt die aktuelle Protokolldatei in eine neue, die neu erstellte Protokolldatei wird nicht mehr mit den Protokollen gefüllt. Es scheint, dass der Dateihandler verloren geht und die Umleitung nicht mehr funktioniert, sobald die ursprüngliche Protokolldatei entfernt wurde.

Ich habe auch gefunden dieser Beitrag Das hatte das gleiche Problem wie ich und behauptet, dass es mit Hilfe behoben werden kann >> anstatt > um die Ausgabe umzuleiten. Ich testete seine Lösung, aber es funktionierte nicht für mich. Hat jemand eine Idee, wie die Weiterleitung funktioniert?


21
2017-07-03 06:23


Ursprung


Ich würde immer noch empfehlen, in Ihrem Fall ">>" anstelle von ">" zu verwenden, wenn Sie in eine abgeschnittene Datei schreiben möchten: wenn ">>" im Append-Modus geöffnet wird, sucht es bis zum Ende der Datei jedes Mal wenn es schreibt. Auf diese Weise, wenn Sie die Datei gestutzt (so dass es auf 0 Bytes von XXXX Bytes gehen), wird es „bis Ende suchen“, so weiß es jetzt nach Byte schreiben hat 0. Ansonsten kann es nach Byte XXXX schreiben und damit Erstelle eine dünn besetzte Datei mit XXXX Null-Bytes davor (dh wenn ">", kann sich die fd einfach merken, wo sie in dieser Datei war, und von dort schreiben, ohne zu realisieren, dass die Dateigröße geschrumpft ist!) - Olivier Dulac


Antworten:


Sie sollten die copytruncate-Anweisung in Ihrer logrotate-Konfiguration für diese Protokolldatei verwenden.

copytruncate   Schneiden Sie die ursprüngliche Protokolldatei nach dem Erstellen einer Kopie ab, anstatt die alte Protokolldatei zu verschieben und optional eine neue zu erstellen. Es kann verwendet werden, wenn einem Programm nicht mitgeteilt werden kann, dass es seine Protokolldatei schließen soll und somit fortfahren könnte, für immer an die vorherige Protokolldatei zu schreiben (anzuhängen). Beachten Sie, dass zwischen dem Kopieren und dem Abschneiden der Datei ein sehr kleiner Zeitabschnitt liegt, sodass einige Protokolldaten verloren gehen können. Wenn diese Option verwendet wird, hat die Option create keine Auswirkung, da die alte Protokolldatei unverändert bleibt


24
2017-07-03 06:26



Kann erwähnenswert sein: Für kurze Zeit, vor dem compressOperation werden die Daten dupliziert. Das hat uns einmal ein Problem gemacht, aber das war unser Nachteil, denn wir hätten nicht so nah dran sein sollen lv Speicherplatzbegrenzung. Auch, wie in der man Snippet können Sie zwischen den Kopier- und Abschneideoperationen einige Protokolldaten verlieren. - Belmin Fernandez


Als Alternative können Sie auch:

  • Verwenden Sie das Logger-Dienstprogramm in Ihrem Skript anstelle von Piping mit einer dedizierten Einrichtung (z. B. local5), zum Beispiel:

    logger -p local5.info -t myscriptname "this is some log data"

  • Konfigurieren Sie syslog, um diese Funktion in die gewünschte Protokolldatei zu schreiben, Beispiel (rsyslog.conf):

    local5.* /var/log/mylogfile

  • Richten Sie die Logrotate-Regel für dieses Protokoll ein.


5
2017-07-03 09:37



Dies funktioniert nur, wenn Sie explizite Ausgabebefehle wie echo. Die Ausgabe von Drittanbieterwerkzeugen, die aus dem Skript aufgerufen werden und auch etwas ausgeben, kann auf diese Weise nicht zum Logger umgeleitet werden - Daniel Alder


Eine andere Alternative zur Iain-Lösung ist die Verwendung von a postrotate Skript, um das Skript neu zu starten, sobald die Rotation stattgefunden hat. Dies wird für viele Daemons getan (Neustart oder Neuladen des Daemons), aber ich kenne Ihr Skript nicht. Ich weiß nicht, ob diese Lösung zu Ihnen passt oder nicht (hängt Ihr Skript von einem Zustand ab, der vor einiger Zeit generiert wurde?).

Inhalt von /etc/logrotate.d/your-script-name:

/var/log/your-script-name.log {
    # your current logrotate options
    ...
    postrotate
        # this supposing you have the current pid stored
        cat /run/your-script-name.pid | xargs -r kill
        #relaunch it again
        /usr/local/bin/your-script-name
    endscript
}

3
2017-07-03 20:43





Sie können stdout auf "split" (Teil von coreutils in linux) pipen. Es erlaubt Ihnen, Datei / stdin in Stücke auf der Grundlage der Größe, der Anzahl der Zeilen usw. zu teilen. Sobald Sie es chunked haben, können Sie es bei Bedarf mit logrotate verwalten.


-1
2018-06-11 18:31