旋转哑非交互应用程序的日志


8

Ubuntu 10.4服务器。

我有一个愚蠢的非交互式旧式服务,该服务在服务器上不断运行。

它正在将其日志写入具有固定名称(/var/log/something.log)的文件。

它不处理任何释放日志文件的信号。我需要旋转该日志文件。

有没有一种方法可以正确地执行此操作而无需更改应用程序且不会丢失日志中的任何数据?

Answers:


5

Ignacio的回答引起了我的兴趣,因此我做了一些研究,并在下面提出了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;
   }
}


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

您还可以使用精心制作的前后旋转脚本和copytruncate选项,使logrotate为您发挥神奇的作用,如下所示:

/ var / log / something {
    日常
    旋转5
    复制截断
    预旋转
        #当然,这假设您有一个pid文件。
        #如果您不这样做,那么它可能像上面一样是一个杀人手段。
        杀死-STOP`cat / var / run / legacyappname.pid`
    尾标
    后旋转
        kill -CONT`cat / var / run / legacyappname.pid`
    尾标
}

有趣的选择,谢谢。在停止期间,与应用程序以及从应用程序的套接字连接会发生什么?我担心断开连接。
亚历山大·格拉迪什

另外,该应用程序正在runit下运行。如果停止应用程序进程,其监视器将如何处理?
亚历山大·格拉迪什

连接的行为取决于设置它们的超时以及执行实际旋转所花费的时间。除非日志很大,否则我不会想象您在那里会遇到任何麻烦。我没有runit的经验,所以无法告诉您显示器如何对停止该进程做出反应。
在2010年

似乎可以与systemd完美配合,该服务在日志轮换发生之前仍显示运行良好。我假设如果我要停止的特定pid,该pid的子进程会继续运行吗?
约瑟夫·佩西

1

您可以尝试让应用程序登录到命名管道,并让某些程序(例如syslog-ng)支持正确的日志轮换机制,以读取日志条目并将其记录到文件中。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.