ダムの非インタラクティブアプリケーションのログをローテーションする


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;
   }
}


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ファイルがあることを前提としています。
        #そうしないと、これは代わりに上記のようなスキルになります。
        kill -STOP `cat / var / run / legacyappname.pid`
    endscript
    後回転
        kill -CONT `cat / var / run / legacyappname.pid`
    endscript
}

興味深いオプション、ありがとう。アプリへのソケット接続と停止中のアプリからのソケット接続はどうなりますか?切断が心配です。
アレクサンダーグラディシュ

また、アプリはrunitで実行されています。アプリのプロセスが停止した場合、モニターは何をしますか?
Alexander Gladysh

接続の動作は、設定されたタイムアウトと、実際のローテーションを実行するのにかかる時間によって異なります。ログが膨大でない限り、問題が発生するとは思いません。runitの使用経験はないので、プロセスの停止に対するモニターの反応はわかりません。
マーク

systemdで完璧に機能しているように見えますが、ログのローテーションが行われる前に、サービスは正常に動作しているように見えます。そして、私が停止していた特定のpidがある場合、pidの子プロセスは実行を継続するのでしょうか?
ジョセフペルシー2017

1

アプリケーションで名前付きパイプにログを記録し、適切なログローテーションメカニズムをサポートするいくつかのプログラム(syslog-ngなど)でログエントリを読み取ってファイルに記録することができます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.