web-dev-qa-db-ja.com

logrotateがファイルを移動した後、stdoutをファイルにリダイレクトし続ける方法は?

一連のログを画面に出力する簡単なスクリプトがあり、STDOUTをファイルにパイプしてログを保存します。このスクリプトは実行時間が長いため、ログファイルをローテーションして、より管理しやすい小さいログにまとめる必要がありました。

私が直面した問題は、logrotateが現在のログファイルを新しいファイルに移動すると、新しく作成されたログファイルにログが追加されなくなるということでした。元のログファイルが削除されると、そのファイルハンドラーが失われ、リダイレクトが機能しなくなるようです。

私はまた この投稿 を見つけました。これは私と同じ問題があり、>>の代わりに>を使用して出力をリダイレクトすることで修正できると主張しています。私は彼のソリューションをテストしましたが、うまくいきませんでした。リダイレクトを維持する方法を知っている人はいますか?

22
Mehran

このログファイルのlogrotate設定でcopytruncateディレクティブを使用する必要があります。

copytruncate古いログファイルを移動してオプションで新しいログファイルを作成する代わりに、コピーの作成後に元のログファイルを切り捨てます。一部のプログラムにログファイルを閉じるように指示できないため、以前のログファイルに永久に書き込み(追加)し続ける可能性がある場合に使用できます。ファイルのコピーと切り捨ての間に非常に小さなタイムスライスがあるため、一部のログデータが失われる可能性があることに注意してください。このオプションを使用すると、古いログファイルがそのまま残るため、作成オプションは無効になります。

25
user9517

別の方法として、次のこともできます。

  • 専用の機能(例:local5)を使用して、パイプの代わりにロガーユーティリティをスクリプトで使用します。次に例を示します。

    logger -p local5.info -t myscriptname "this is some log data"

  • この機能を必要なログファイルに書き込むようにsyslogを構成します。例(rsyslog.conf):

    local5.* /var/log/mylogfile

  • このログのlogrotateルールを設定します。

6
tonioc

Iainソリューションの別の代替方法は、ローテーションが行われたら、postrotateスクリプトを使用してスクリプトを再起動することです。これは多くのデーモン(デーモンの再起動または再読み込み)に対して行われますが、スクリプトがわからないこのソリューションが適しているかどうかはわかりません(スクリプトは以前に生成された状態に依存していますか?)。

の内容 /etc/logrotate.d/your-script-name

/var/log/your-script-name.log {
    # your current logrotate options
    ...
    postrotate
        # this supposing you have the current pid stored
        cat /run/your-script-name.pid | xargs -r kill
        #relaunch it again
        /usr/local/bin/your-script-name
    endscript
}
4

Stdoutを "split"(linuxのcoreutilsの一部)にパイプすることができます。サイズ、行数などに基づいてファイル/標準入力をチャンクに分割できます。チャンクを取得したら、必要に応じてlogrotateで管理できます。

0
Nazar