Girar logs de um aplicativo não interativo burro

8

Servidor Ubuntu 10.4.

Eu tenho um serviço legado não interativo burro, que está sendo executado constantemente no meu servidor.

Ele está gravando seu log em um arquivo com nome fixo (/var/log/something.log).

Ele não manipula nenhum sinal para liberar o arquivo de log. Eu preciso girar esse arquivo de log.

Existe uma maneira de fazer isso corretamente sem alterar o aplicativo e sem perder dados no log?

Alexander Gladysh
fonte

Respostas:

5

A resposta de Ignacio me intrigou, então eu fiz algumas pesquisas e criei o script Perl abaixo. Se o seu serviço gravar em um pipe nomeado, ele deverá funcionar e ser usado com o logrotate.

Para que ele funcione, você precisa transformar seu arquivo de log em um pipe nomeado. Renomeie o arquivo existente e

mkfifo /var/log/something.log

e editar os três nomes de arquivos para atender aos seus requisitos. Execute seu serviço e, em seguida, este daemon, que deve ler o pipe nomeado e gravá-lo em um novo arquivo de log.

Se você renomear, em /var/log/somethingrotateable.logseguida, envie um HUP para o daemon, ele será gerado automaticamente e criará um novo somethingrotateable.logpara o qual gravar. Se estiver usando logrotate, um 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
fonte
8

Efetue logon em um FIFO, depois execute um daemon que se conecte ao outro lado do FIFO e tenha manipuladores de sinal que permitem girar o log.

Ignacio Vazquez-Abrams
fonte
2

Envie SIGSTOP para o processo, copie o log para outro nome, trunque o log, envie SIGCONT para o processo, talvez assim:

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

Você também pode fazer com que o logrotate faça a mágica para você com scripts de pré e pós-rotação cuidadosamente criados e a opção copytruncate, da seguinte maneira:

/ var / log / alguma coisa {
    diariamente
    rodar 5
    copytruncate
    prerrogar
        # Isso pressupõe que você tenha um arquivo pid, é claro.
        # Se não o fizer, pode ser um pkill como acima.
        kill -STOP `cat / var / run / legacyappname.pid`
    final
    postrotado
        kill -CONT `cat / var / run / legacyappname.pid`
    final
}
marca
fonte
Opção interessante, obrigado. O que acontecerá com as conexões de soquete ao aplicativo e dele durante a parada? Estou preocupado com desconexões.
Alexander Gladysh 11/11/10
Além disso, o aplicativo está sendo executado no runit. O que o monitor fará se o processo do aplicativo for interrompido?
Alexander Gladysh 11/11/10
O comportamento das conexões dependeria do tempo limite com o qual foram definidas e do tempo necessário para fazer a rotação real. Eu não imaginaria que você teria algum problema lá, a menos que os logs sejam enormes. Eu não tenho nenhuma experiência com runit, então não pude dizer como o monitor reagirá ao interromper o processo.
marque
Parece funcionar perfeitamente com o systemd, o serviço ainda mostra como funcionando muito antes da rotação do log. E estou assumindo que, se o pid específico que eu estava parando, os processos filhos do pid continuariam em execução?
Joseph Persie
1

Você pode tentar deixar o aplicativo registrar em um canal nomeado e ter algum programa (por exemplo, syslog-ng ) que ofereça suporte a mecanismos adequados de rotação de logs, leia as entradas de log e registre-as em um arquivo.

vwegert
fonte