Faire pivoter les journaux d'une application non interactive muette

8

Serveur Ubuntu 10.4.

J'ai un service hérité non interactif stupide qui fonctionne constamment sur mon serveur.

Il écrit son journal dans un fichier avec un nom fixe (/var/log/something.log).

Il ne gère aucun signal pour lâcher le fichier journal. J'ai besoin de faire pivoter ce fichier journal.

Existe-t-il un moyen de le faire correctement sans modifier l'application et sans perdre de données dans le journal?

Alexander Gladysh
la source

Réponses:

5

La réponse d'Ignacio m'a intrigué alors j'ai fait quelques recherches et j'ai trouvé le script Perl ci-dessous. Si votre service écrit sur un canal nommé, il devrait fonctionner et être utilisable avec logrotate.

Pour que cela fonctionne, vous devez transformer votre fichier journal en un canal nommé. Renommez le fichier existant puis

mkfifo /var/log/something.log

et de modifier les 3 noms de fichiers pour répondre à vos besoins. Exécutez votre service puis ce démon qui doit lire le canal nommé et l'écrire dans un nouveau fichier journal.

Si vous renommez /var/log/somethingrotateable.logpuis envoyez un HUP au démon, il se reproduira et en créera un nouveau somethingrotateable.logpour écrire. Si vous utilisez logrotate, un postrotatescript dekill -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;
   }
}
user9517
la source
8

Connectez-vous à un FIFO, puis exécutez un démon qui se connecte à l'autre côté du FIFO et dispose de gestionnaires de signaux qui vous permettent de faire pivoter le journal.

Ignacio Vazquez-Abrams
la source
2

Envoyez SIGSTOP au processus, copiez le journal sous un autre nom, tronquez le journal, envoyez SIGCONT au processus, peut-être comme ceci:

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

Vous pouvez également laisser logrotate faire la magie pour vous avec des scripts de pré et post rotation soigneusement conçus et l'option copytruncate, comme ceci:

/ var / log / quelque chose {
    du quotidien
    tourner 5
    copiertronquer
    préroter
        # Cela suppose que vous ayez un fichier pid, bien sûr.
        # Si vous ne le faites pas, cela pourrait être un avantage comme ci-dessus.
        kill -STOP `cat / var / run / legacyappname.pid`
    script de fin
    post-rotation
        kill -CONT `cat / var / run / legacyappname.pid`
    script de fin
}
marque
la source
Option intéressante, merci. Que se passera-t-il avec les connexions socket à l'application et à partir de celle-ci pendant l'arrêt? Je m'inquiète des déconnexions.
Alexander Gladysh
En outre, l'application est exécutée sous runit. Que fera son moniteur si le processus d'application est arrêté?
Alexander Gladysh
Le comportement des connexions dépend de la temporisation avec laquelle elles sont définies et du temps nécessaire pour effectuer la rotation réelle. Je n'imaginerais pas que vous auriez des ennuis à moins que les journaux soient énormes. Je n'ai aucune expérience avec runit donc je ne pourrais pas vous dire comment le moniteur réagira à l'arrêt du processus.
marquez
Semble fonctionner parfaitement avec systemd, le service montre toujours qu'il fonctionne bien avant la rotation du journal. Et je suppose que si le pid particulier que j'arrêtais, les processus enfants du pid continueraient-ils de fonctionner?
Joseph Persie
1

Vous pouvez essayer de laisser le journal des applications à un canal nommé et avoir un programme (par exemple syslog-ng ) qui prend en charge les mécanismes de rotation des journaux appropriés lire les entrées de journal et les enregistrer dans un fichier.

vwegert
la source