旋转愚蠢的非交互式应用程序的日志

Ubuntu 10.4服务器。

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

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

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

有没有办法做到这一点,而不需要改变应用程序,也不会丢失日志中的任何数据?

伊格纳西奥的回答让我感兴趣,所以我做了一些研究,并提出了下面的Perl脚本。 如果你的服务将写入一个命名的pipe道,它应该工作,并可以使用logrotate。

为了工作,你需要把你的日志文件放到一个命名pipe道中。 然后重命名现有的文件

mkfifo /var/log/something.log 

并编辑3个文件名以符合您的要求。 运行你的服务,然后这个守护进程应该读取命名pipe道,并将其写入一个新的日志文件。

如果你重命名/var/log/somethingrotateable.log然后发送一个HUP到守护进程,它会自己产生并创build一个新的somethingrotateable.log来写入。 如果使用kill -HUP 'cat /var/run/yourpidfile.pid'postrotate脚本,

 #!/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; } } 

login到一个FIFO,然后运行一个守护进程,连接到FIFO的另一端,并有信号处理程序,允许您旋转日志。

将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通过精心devise的前后旋转脚本和copytruncate选项来为你做出魔法,就像这样:

 / var / log / something {
    日常
    旋转5
     copytruncate
     prerotate
         #这个假设你有一个pid文件,当然。
         #如果你不这样做,这可能是一个像上面的pkill。
         kill -STOP`cat / var / run / legacyappname.pid`
     endscript
     postrotate
        杀死-CONT`cat / var / run / legacyappname.pid`
     endscript
 }

您可以尝试让应用程序login到命名pipe道,并让一些支持正确日志循环机制的程序(例如syslog-ng )读取日志条目并将其logging到文件中。