Поворот логов тупого неинтерактивного приложения

8

Сервер Ubuntu 10.4.

У меня тупой неинтерактивный устаревший сервис, который постоянно работает на моем сервере.

Он записывает свой журнал в файл с фиксированным именем (/var/log/something.log).

Он не обрабатывает какие-либо сигналы, чтобы отпустить файл журнала. Мне нужно повернуть этот файл журнала.

Есть ли способ сделать это правильно, не меняя приложение и не теряя данные в журнале?

Александр Гладыш
источник

Ответы:

5

Ответ Игнасио заинтриговал меня, поэтому я провел небольшое исследование и предложил сценарий Perl ниже. Если ваш сервис будет писать в именованный канал, он должен работать и использоваться с logrotate.

Чтобы это работало, вам нужно превратить ваш лог-файл в именованный канал. Затем переименуйте существующий файл

mkfifo /var/log/something.log

и отредактировать 3 имени файла в соответствии с вашими требованиями. Запустите ваш сервис, затем этот демон, который должен прочитать именованный канал и записать его в новый лог-файл.

Если вы переименуете, /var/log/somethingrotateable.logто отправите HUP демону, он сам появится и создаст новый somethingrotateable.logдля записи. При использовании logrotate 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;
   }
}
user9517
источник
8

Войдите в FIFO, затем запустите демон, который подключается к другой стороне FIFO и имеет обработчики сигналов, которые позволяют вращать журнал.

Игнасио Васкес-Абрамс
источник
2

Отправьте 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 / что-то {
    ежедневно
    повернуть 5
    copytruncate
    prerotate
        # Это предполагает, что у вас есть файл pid, конечно.
        # Если вы этого не сделаете, это может быть pkill как выше.
        kill -STOP `cat / var / run / legacyappname.pid`
    endscript
    postrotate
        kill -CONT `cat / var / run / legacyappname.pid`
    endscript
}
отметка
источник
Интересный вариант, спасибо. Что будет с сокетными подключениями к приложению и от него во время остановки? Я беспокоюсь о разрывах.
Александр Гладыш
Также приложение запускается под управлением runit. Что будет делать его монитор, если процесс приложения остановлен?
Александр Гладыш
Поведение соединений будет зависеть от времени ожидания, с которым они установлены, и времени, которое требуется для фактического вращения. Я не думаю, что у вас возникнут какие-либо проблемы, если бревна огромные. У меня нет опыта работы с runit, поэтому я не могу сказать вам, как монитор отреагирует на остановку процесса.
отметка
Кажется, что он отлично работает с systemd, служба по-прежнему показывает, что работает задолго до ротации журналов. И я предполагаю, что если конкретный pid я остановил, продолжатся ли дочерние процессы pid?
Джозеф Перси
1

Вы можете попытаться разрешить приложению вести журнал в именованный канал и иметь некоторую программу (например, syslog-ng ), которая поддерживает надлежащие механизмы ротации журналов, читает записи журнала и записывает их в файл.

vwegert
источник