2011-06-28 2 views
8

logrotateと互換性のあるファイルライター/ロガーをJavaで実装するためのベストプラクティスは何ですか?目標は、ログAPI(Log4Jなど)の組み込みのローテーション/管理を使用する代わりに、すべてのログ管理にlogrotateを使用できるようにすることです。Javaや他のプラットフォームでlogrotate friendlyファイルライターを作成するにはどうすればよいですか?

私は、Java以外にも、他の開発プラットフォームのコメント/回答を聞くことに興味があります。

答えて

8

アプリケーション内のログファイルを定期的に閉じて再度開くだけで済みます。最後の終了時刻を保持するハンドラが必要です。最後のクローズから20秒が経過し、ログエントリが書き込まれる直前である場合、ハンドラはファイルを閉じて再オープンする必要があります。ログエントリを書き込む直前にこのようなチェックを行う必要があります

これを行わないと、logrotate(!)で名前が変更されてもログは古いファイルに書き込まれます(ファイルディスクリプタは同じままです)。ログが圧縮されて削除されると、ログエントリは消えてしまいます(このような場合、javaはそのようなログを静かに削除します)。

ファイル名を使用してログを閉じて再オープンすると、ファイルの名前が変更された場合に新しいファイルが作成されます。ログを書き込むたびにファイルを閉じて再オープンするのは、ファイルを開くのはコストのかかる操作なので、過剰な作業です。

0

私はいくつかのアプリを見て、明らかにpostrotateオプションとcopytruncate optionがあります。 copytruncateオプションは簡単ですが、バッファがフラッシュされない(つまり、@Jarek Potuikの答えに従う)ので、信頼性が低いと思います。重複したエントリや削除されたエントリを取得する可能性があります。

は、このようにあなたがpostrotateオプションをしたいと仮定することができます:

postrotateオプションでは、(クローズしてからオープン)ファイルを再度開くようにアプリケーションを指示するコマンドを実行することができます。 Javaでファイルを開いたり閉じたりしている間は、同期化されたブロックや何らかのロックを使用してこれを行い、もちろんバッファーをフラッシュします。

アプリがmyappと呼ばれていると仮定しましょう:

次のようなもので/etc/logrotate.d/myapp内のファイルを持っているでしょう:

/var/log/myapp/*.log { 
     weekly 
     missingok 
     rotate 20 
     compress 
     delaycompress 
     notifempty 
     sharedscripts 
     postrotate 
      /etc/init.d/myapp rotate-logs > /dev/null 
     endscript 
} 

コマンド/etc/init.d/myapp rotate-logsは、ログを閉じて再度開くアプリに合図する必要がありますファイル。

シグナリングの部分は、JavaがIPC(つまりUnix信号)をサポートしていないため、あなたが持っているアプリケーションの種類によって異なります。したがって、ポートを開いたり、8080などの既存のポートサーブレットコンテナの場合はHTTP RESTコマンド)を使用して、アプリケーションにログファイルを閉じて再度開くよう指示します。

関連する問題