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


22

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

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

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


4
切り捨てられたファイルに書き込む場合は、「>」ではなく「>>」を使用することをお勧めします。追加モードで「>>」を開くと、ファイルの最後までシークされます書き込むたびに。そうすれば、ファイルを切り捨てる(XXXXバイトから0バイトにする)ときに「最後までシークする」ので、バイト0の後に書き込む必要があることがわかります。そうでない場合、バイトXXXXの後に書き込む可能性があります。 XXXX nullバイトの前にスパースファイルを作成します(つまり、 ">"の場合、fdはそのファイルの場所を記憶し、ファイルサイズが縮小することなくそこから書き込むことができます!)
Olivier Dulac 14

回答:


25

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

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


2
言及する価値があるかもしれません:少しの間、compress操作の前に、データが複製されます。それは私たちに一度問題を引き起こしましたが、lvスペース制限にそれほど近づいてはならないので、それは私たちの悪いことでした。また、manスニペットで述べたように、コピー操作と切り捨て操作の間にいくつかのログデータが失われる可能性があります。
ベルミンフェルナンデス14

6

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

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

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

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

    local5.* /var/log/mylogfile

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


これは、などの明示的な出力コマンドがある場合にのみ機能しますecho。スクリプトから呼び出され、また何かを出力するサードパーティ製ツールの出力は、この方法でロガーにリダイレクトできません
ダニエルアルダー

4

Iainソリューションのもう1つの代替方法は、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
}

0

標準出力を「分割」(Linuxのcoreutilsの一部)にパイプできます。サイズ、行数などに基づいてファイル/標準入力をチャンクに分割できます。チャンク化したら、必要に応じてlogrotateで管理できます。

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