Rotar registros de una aplicación no interactiva tonta

8

Servidor Ubuntu 10.4.

Tengo un servicio heredado no interactivo tonto que se ejecuta constantemente en mi servidor.

Está escribiendo su registro en un archivo con nombre fijo (/var/log/something.log).

No maneja ninguna señal para soltar el archivo de registro. Necesito rotar ese archivo de registro.

¿Hay alguna manera de hacer esto correctamente sin cambiar la aplicación y sin perder ningún dato en el registro?

Alexander Gladysh
fuente

Respuestas:

5

La respuesta de Ignacio me intrigó, así que investigué un poco y encontré el guión de Perl a continuación. Si su servicio escribirá en una tubería con nombre, debería funcionar y ser utilizable con logrotate.

Para que funcione, debe convertir su archivo de registro en una tubería con nombre. Cambie el nombre del archivo existente y luego

mkfifo /var/log/something.log

y para editar los 3 nombres de archivo para cumplir con sus requisitos. Ejecute su servicio y luego este demonio que debería leer la tubería con nombre y escribirla en un nuevo archivo de registro.

Si cambia el nombre /var/log/somethingrotateable.log, envíe un HUP al demonio, se generará y creará un nuevo somethingrotateable.logpara escribir. Si usa 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;
   }
}
usuario9517
fuente
8

Inicie sesión en un FIFO, luego ejecute un demonio que se conecta al otro lado del FIFO y tiene controladores de señal que le permiten rotar el registro.

Ignacio Vazquez-Abrams
fuente
2

Enviar SIGSTOP al proceso, copiar el registro a otro nombre, truncar el registro, enviar SIGCONT al proceso, tal vez así:

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

También puede hacer que logrotate haga la magia por usted con scripts de rotación previa y posterior cuidadosamente diseñados y la opción copytruncate, de esta manera:

/ var / log / something {
    diario
    rotar 5
    copytruncate
    prerrotación
        # Esto supone que tiene un archivo pid, por supuesto.
        # Si no lo hace, esto podría ser un pkill como el anterior.
        kill -STOP `cat / var / run / legacyappname.pid`
    escritura final
    postrotar
        kill -CONT `cat / var / run / legacyappname.pid`
    escritura final
}
marca
fuente
Opción interesante, gracias. ¿Qué sucederá con las conexiones de socket a la aplicación y desde ella durante la parada? Me preocupan las desconexiones.
Alexander Gladysh
Además, la aplicación se ejecuta bajo runit. ¿Qué hará su monitor si se detiene el proceso de la aplicación?
Alexander Gladysh
El comportamiento de las conexiones dependería del tiempo de espera con el que están configuradas y el tiempo que lleva hacer la rotación real. No me imagino que te encontrarás con ningún problema a menos que los registros sean enormes. No tengo ninguna experiencia con runit, así que no podría decirte cómo reaccionará el monitor al detener el proceso.
marca el
Parece funcionar perfectamente con systemd, el servicio aún se muestra como funcionando mucho antes de que se produjera la rotación del registro. Y supongo que si el pid particular que estaba deteniendo, ¿continuarían ejecutándose los procesos hijos del pid?
Joseph Persie
1

Puede intentar dejar que la aplicación inicie sesión en una tubería con nombre y tener algún programa (por ejemplo, syslog-ng ) que admita mecanismos de rotación de registro adecuados para leer las entradas de registro y registrarlas en un archivo.

vwegert
fuente