Сервер Ubuntu 10.4.
У меня есть тупая неинтерактивная устаревшая служба, которая постоянно работает на моем сервере.
Он записывает свой журнал в файл с фиксированным именем (/var/log/something.log).
Он не обрабатывает никаких сигналов, чтобы отпустить файл журнала. Мне нужно повернуть этот файл журнала.
Есть ли способ сделать это правильно, не меняя приложение и не теряя никаких данных в журнале?
Войдите в FIFO, затем запустите демон, который подключается к другой стороне FIFO и имеет обработчики сигналов, которые позволяют вам вращать журнал.
Ответ Игнасио заинтриговал меня, поэтому я провел небольшое исследование и придумал сценарий Perl ниже. Если ваш сервис будет писать в именованный канал, он должен работать и использоваться с logrotate.
Чтобы это работало, вам нужно превратить ваш лог-файл в именованный канал. Переименуйте существующий файл, затем
mkfifo /var/log/something.log
и отредактировать 3 имени файла в соответствии с вашими требованиями. Запустите службу, а затем этот демон, который должен прочитать именованный канал и записать его в новый файл журнала.
Если вы переименуете /var/log/somethingrotateable.log
затем отправьте HUP демону, который создаст сам себя и создаст новый somethingrotateable.log
написать. При использовании logrotate a postrotate
сценарий kill -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;
}
}
Отправить SIGSTOP процессу, скопировать журнал на другое имя, обрезать журнал, отправить SIGCONT процессу, возможно, так:
pkill -STOP legacyappname cp /var/log/something.log /var/log/something.log.backup cat /dev/null > /var/log/something.log pkill -CONT legacyappname
Вы также можете использовать logrotate, который сделает за вас магию с помощью тщательно разработанных сценариев до и после вращения и опции copytruncate, например:
/var/log/something { daily rotate 5 copytruncate prerotate # This assumes you have a pid file, of course. # If you don't, this could instead be a pkill like above. kill -STOP `cat /var/run/legacyappname.pid` endscript postrotate kill -CONT `cat /var/run/legacyappname.pid` endscript }
Вы можете попытаться разрешить приложению войти в именованный канал и иметь какую-нибудь программу (например syslog-ng), который поддерживает надлежащие механизмы ротации журналов, считывает записи журнала и записывает их в файл.