Drehen Sie Protokolle einer nicht interaktiven Anwendung

8

Ubuntu 10.4 Server.

Ich habe einen blöden, nicht interaktiven Legacy-Dienst, der ständig auf meinem Server ausgeführt wird.

Es schreibt sein Protokoll in eine Datei mit festem Namen (/var/log/something.log).

Es werden keine Signale zum Loslassen der Protokolldatei verarbeitet. Ich muss diese Protokolldatei drehen.

Gibt es eine Möglichkeit, dies ordnungsgemäß zu tun, ohne die Anwendung zu ändern und ohne Daten im Protokoll zu verlieren?

Alexander Gladysh
quelle

Antworten:

5

Die Antwort von Ignacio hat mich fasziniert, also habe ich ein paar Nachforschungen angestellt und das Perl-Skript unten entwickelt. Wenn Ihr Dienst in eine Named Pipe schreibt, sollte er funktionieren und mit Logrotate verwendet werden können.

Damit dies funktioniert, müssen Sie Ihre Protokolldatei in eine Named Pipe umwandeln. Benennen Sie dann die vorhandene Datei um

mkfifo /var/log/something.log

und die 3 Dateinamen zu bearbeiten, um Ihre Anforderungen zu erfüllen. Führen Sie Ihren Dienst dann diesen Daemon aus, der die Named Pipe lesen und in eine neue Protokolldatei schreiben soll.

Wenn Sie umbenennen /var/log/somethingrotateable.log, wird ein HUP an den Daemon gesendet, der sich selbst erzeugt und ein neues erstellt, somethingrotateable.login das geschrieben werden kann. Wenn Sie logrotate verwenden, schreiben Sie ein postrotateSkript vonkill -HUP 'cat /var/run/yourpidfile.pid'

#!/usr/bin/perl -w
use POSIX ();
use FindBin ();
use File::Basename ();
use File::Spec::Functions;
#
$|=1;
#
# Change the 3 filenames and paths below to meet your requirements.
#
my $FiFoFile = '/var/log/something.log';
my $LogFile = '/var/log/somethingrotateable.log';
my $PidFile = '/var/run/yourpidfile.pid';

# # make the daemon cross-platform, so exec always calls the script
# # itself with the right path, no matter how the script was invoked.
my $script = File::Basename::basename($0);
my $SELF = catfile $FindBin::Bin, $script;
#
# # POSIX unmasks the sigprocmask properly
my $sigset = POSIX::SigSet->new();
my $action = POSIX::SigAction->new('sigHUP_handler',$sigset,&POSIX::SA_NODEFER);
POSIX::sigaction(&POSIX::SIGHUP, $action);

sub sigHUP_handler {
#    print "Got SIGHUP";
    exec($SELF, @ARGV) or die "Couldn't restart: $!\n";
   }

#open the logfile to write to
open(LOGFILE, ">>$LogFile") or die "Can't open $LogFile";
open(PIDFILE, ">$PidFile") or die "Can't open PID File $PidFile";
print PIDFILE "$$\n";
close PIDFILE;
readLog();

sub readLog {
sysopen(FIFO, $FiFoFile,0)  or die "Can't open $FiFoFile";
while ( my $LogLine = <FIFO>) {
    print LOGFILE $LogLine;
   }
}
user619714
quelle
7

Melden Sie sich bei einem FIFO an, und führen Sie dann einen Dämon aus, der eine Verbindung zur anderen Seite des FIFO herstellt und über Signalhandler verfügt, mit denen Sie das Protokoll drehen können.

Ignacio Vazquez-Abrams
quelle
2

Senden Sie SIGSTOP an den Prozess, kopieren Sie das Protokoll in einen anderen Namen, kürzen Sie das Protokoll, senden Sie SIGCONT an den Prozess, vielleicht so:

pkill -STOP LegacyAppname
cp /var/log/something.log /var/log/something.log.backup
cat / dev / null> /var/log/something.log
pkill -CONT LegacyAppname

Sie können sich auch von logrotate mit sorgfältig ausgearbeiteten Skripten vor und nach der Rotation und der Option copytruncate zaubern lassen:

/ var / log / something {
    Täglich
    drehen 5
    copytruncate
    vorrotieren
        # Dies setzt natürlich voraus, dass Sie eine PID-Datei haben.
        # Wenn Sie dies nicht tun, könnte dies stattdessen ein Pkill wie oben sein.
        kill -STOP `cat / var / run / legacyappname.pid`
    Endskript
    nachrotieren
        kill -CONT `cat / var / run / legacyappname.pid`
    Endskript
}
Kennzeichen
quelle
Interessante Option, danke. Was passiert mit Socket-Verbindungen zur App und von dort während des Stopps? Ich mache mir Sorgen um Verbindungsabbrüche.
Alexander Gladysh
Außerdem wird die App unter runit ausgeführt. Was macht der Monitor, wenn der App-Prozess gestoppt wird?
Alexander Gladysh
Das Verhalten der Verbindungen hängt vom eingestellten Timeout und der Zeit ab, die für die eigentliche Rotation benötigt wird. Ich würde mir nicht vorstellen, dass Sie dort Ärger bekommen, wenn die Protokolle nicht riesig sind. Ich habe keine Erfahrung mit runit und kann Ihnen daher nicht sagen, wie der Monitor auf das Stoppen des Prozesses reagiert.
Markieren Sie den
Scheint perfekt mit systemd zusammenzuarbeiten. Der Dienst läuft noch lange bevor die Protokollrotation stattgefunden hat. Und ich gehe davon aus, dass, wenn die bestimmte PID, die ich gestoppt habe, die untergeordneten Prozesse der PID weiterhin ausgeführt werden?
Joseph Persie
1

Sie können versuchen, die Anwendung in einer Named Pipe protokollieren zu lassen und ein Programm (z. B. syslog-ng ) verwenden, das ordnungsgemäße Protokollrotationsmechanismen unterstützt, um die Protokolleinträge zu lesen und in einer Datei zu protokollieren.

vwegert
quelle