轮换非交互式应用程序的日志

轮换非交互式应用程序的日志

Ubuntu 10.4 服务器。

我有一个愚蠢的非交互式遗留服务,它一直在我的服务器上运行。

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

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

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

答案1

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

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

答案3

向进程发送 SIGSTOP,将日志复制到另一个名称,截断日志,向进程发送 SIGCONT,可能像这样:

pkill -STOP 旧应用程序名称
cp /var/log/something.log /var/log/something.log.backup
cat /dev/null > /var/log/something.log
pkill -CONT 旧应用程序名称

您还可以使用精心编写的旋转前和旋转后脚本以及 copytruncate 选项让 logrotate 为您完成神奇的工作,如下所示:

/var/log/某物{
    日常的
    旋转 5
    复制截断
    预旋转
        # 当然,这假设您有一个 pid 文件。
        # 如果你不这样做,这可能会像上面一样成为 pkill。
        kill-STOP`cat /var/run/legacyappname.pid`
    结束语
    后旋转
        kill -CONT `cat /var/run/legacyappname.pid`
    结束语
}

答案4

您可以尝试让应用程序登录到命名管道并有一些程序(例如系统日志工具) 支持适当的日志轮换机制,读取日志条目并将其记录到文件中。

相关内容