stdoutのログローテーション?


53

情報をstdoutとstderrに書き込むことができるLinuxプログラムがあります。

その出力をのファイルにリダイレクトするシェルスクリプトがあります/var/log。(Via >>および2>&1。)

そのログファイルをローテーションさせる方法はありますか?(最大サイズ、別のファイルに切り替え、限られた数のファイルのみを保持)

私はlogrotateプログラムについて話すいくつかの回答を見てきましたが、それは良い音ですが、それらはログファイルを内部的に生成し、HUPシグナルを処理するプログラムにも焦点を当てているようです。基本的な出力リダイレクトスクリプトでこの作業を行う方法はありますか?


1
出力をリダイレクトするスクリプトを変更して、回転のロジックを含めることができないのはなぜですか?
MaQleod

誰かがログファイルのサイズを検出し、そのプロセスを妨害することなくプロセスの標準出力の下からそれを回転させる方法を教えてくれれば、私はできました。私はしていない持って使用するlogrotateだけの議論のための便利な出発点のように聞こえたことを、より良いオプションがあるかどう。
ミラル

2
logrotateを使用する必要はありませんが、logrotateを使用するだけで時間を節約できます...通常、車輪を再発明することはほとんど意味がありません。
-bubu

まさに私のポイント。では、進行中のプロセスのリダイレクトされた標準出力でlogrotateを機能させる方法はありますか?
ミラル

回答:


44

別の方法として、次のような、サイズが制限され、自動的にローテーションされるログファイルセットを維持することを主な目的として設計されたツールを通じて出力をパイプ処理できます。

  • multilogデーモンツールのダン・バーンスタイン
  • multilogdaemontools-encore のBruce Guenter氏
  • ローランBercotのs6-logS6から
  • svlogdRunitのGerrit Pape
  • ウェインマーシャルのtinylogパープから
  • cyclogからの間食

次にmultilog-formatログファイルセットを処理するツールには、次のものが含まれます。

参考文献


1
おかげで、multilog私が必要としていたように見えます。
ミラル

multilogはdebianで唯一のプラグアンドプレイソリューションのようです(daemontoolsには公式パッケージがあります)。しかし、fat32パーティションにログを保存したい私の特定のケースでは、マルチログはシンボリックリンクを使用するため、回転は機能しません。プラグアンドプレイがありません:)
Arnout

multilogどこにもシンボリックリンクを作成したり要求したりすることはないため、それは真実ではありません。それらに関しては完全に中立です。
JdeBP

「今世紀はlogrotateまたはnewsyslogを使用しないでください」のURLに余分なドットがあります
duyue

15

rotatelogsapacheに同梱されているツール(bindir内)(docsを参照)は、stdinからの入力を受け取り、特定の時間後にログをローテーションします


14

標準ログストリーム(syslog、デーモン、cron、ユーザー、セキュリティ、メールなど)のいずれかにアクセスできる場合は、logger代わりにコマンドとパイプを使用できます。

echo "Hello." | logger -p daemon.info

そうでない場合は、ログに記録されたコンテンツをカスタムプログラムまたはスクリプトにパイプして処理するか、logrotate構成のセットアップを検討することをお勧めします。

編集:JdeBPの答えはあなたが探しているかもしれないものを持っているようです。


2
シンプルにするために+1。ところで、標準的なもの(例ではデーモン)の代わりにカスタム機能(local0)を構成することもできます
ロジャーキーズ

14

私は同様の問題を抱えていて、最初はlogrotateを破棄しましたが、logrotateは実際にこれをうまく実行できることが判明しました。主要なディレクティブは「copytruncate」です。何らかの理由で、この用語は私が行ったグーグルのいずれにも出てこなかったので、この答えを追加して、このケースでの使用方法を正確に明確にします。

トリックは、リダイレクトが「>」(作成)ではなく「>>」(追加)で行われた場合にのみ機能します。

構成ファイル(truncate.cfg):

/tmp/temp.log {
    size 10M
    copytruncate
    rotate 4
    maxage 100
}

テストプログラム(決してファイルを放棄しない)。ディスクがいっぱいになるのを見ることができますが、ログファイルを削除しても動作するように見えますが、実際にはディスク上のスペースを解放しません:

cat /dev/urandom >> /tmp/temp.log

実行中のログローテーション:

logrotate truncate.cfg

これは素晴らしい理論ですが、実際に試したどのシステムでも動作しません。ファイルは実際には切り捨てられず、プログラムは以前と同様に追加を続けます。(そして、はい、それは>>経由のリダイレクトでもです。)((ところで、この答えは既に以前に与えられました。))
Miral 14年

1
logrotateで説明したように、元のファイルは切り捨てられません(Unix&Linuxサイト上)。また、echo /dev/urandom >> /tmp/temp.log13個の確定文字を書き込み/tmp/temp.log、すぐに終了します。という意味cat /dev/urandomですか?
Gマンは「Reinstate Monica」14年

2
ここでテストしたところ、うまくいくようです。ファイルの内容が新しいログファイルにコピーされます。元のファイルはプロセスによって開かれたままになり、切り捨てられます(サイズは0になりました)。
フィリップ

1
copytruncateでデータが失われる可能性があることに注意してください。
wanghq

1
+1「ファイルのコピーと切り捨ての間には非常に短いタイムスライスがあるため、一部のログデータが失われる可能性があることに注意してください。」
タガー

3

では、進行中のプロセスのリダイレクトされた標準出力でlogrotateを機能させる方法はありますか?

はい!logrotateが提供する「copytruncate」ディレクティブを確認してください。この状況を処理するようにlogrotateに指示することを指定する:ログファイルを無期限に開いたままにする単純なプログラム。

1つの注意事項は、状況によって問題になる場合とそうでない場合があります。

ファイルのコピーと切り捨ての間には非常に短いタイムスライスがあるため、一部のログデータが失われる可能性があることに注意してください。

逸話的に、私はユーザーがこのディレクティブを適用することを奨励する「現実世界」のログソースを見てきました。このオプションの説明はここにあります


3

分割を使用します。これはcoreutilsの一部です。標準入力を取り、チャンクに分割できます(チャンクサイズや行数などに基づいて)。

例:

app | split --bytes 1G - /var/logs/put-prefix-here

注ダッシュ(-)は、ファイルの代わりにstdinを使用するように「分割」を指示します。


答えを広げて、その方法を説明できますか?ありがとう。
fixer1234

例で私の返信を更新しました。
ナザール

1Gは任意のサイズですが、その後新しいファイルを開始しますか?
fixer1234

1
これは、あるファイルでは半分のメッセージで、次のファイルでは半分のメッセージになる可能性があるため、この問題に対する特に良い解決策ではありません。またsplit、大きなバッファになる可能性のある場所にデータがあるときにマシンがクラッシュすると、データ損失のリスクがあります。この問題を適切に解決するツールが複数あることを考えると、この種のロールユア独自のソリューションはまったく推奨できないと思います。
デビッドリチャービー

1
@David Richerby-バッファなしの-uを追加する方法は?
ニック

3

multilog私のユースケースは好きですが、私のユースケースは非常に単純で単純なので、見つけたドキュメント/例では非常に単純にレイアウトされていません。次に、簡単なマルチログローテーションの例を示します。

mkdir /tmp/myapp
./myapp | multilog t s10000 n5 '!tai64nlocal' /tmp/myapp 2>&1

いくつかのメモ:

  • これは/ tmp / myapp /ディレクトリにログをダンプします
  • s10000は10,000バイトを表します*
  • n5は5つのファイルを表します。*「現在の」ログはファイルの1つとしてカウントされるため、これには4つの古いログ+「現在の」ログが含まれます。
  • これは、FrançoisBeausoleilが提供する例に基づいています:http : //blog.teksol.info/pages/daemontools/best-practices
  • 私は多くのオプションを理解していません-これを拡張するために様々なドキュメントを参照します...
  • ドキュメントは次のように警告しています:"Note that running processor may block any program feeding input to multilog."「プロセッサ」は'!tai64nlocal'コマンドの一部です

*多くのアプリケーションでは、これらは長期使用には適していません。これらを使用すると、大きなログよりも早くログをいっぱいにしてローテーションする動作を観察できます。

最後に、必要に応じてnohupを忘れないでください!nohupを使用すると、2>&1(s = 10e6およびn = 30 は必要ありません):

mkdir -p /tmp/myapp
nohup ./myapp | multilog t s10000000 n30 '!tai64nlocal' /tmp/myapp &

そのコマンドはあなたを始めるはずです。


1

上記のSam Hendleyのコメントに追加したいだけです。

トリックは、リダイレクトが(作成)>>ではなく(追加)で行われた場合にのみ機能し>ます。

私は同じ問題に遭遇し、元のファイル>が(作成)を使用すると成長し続けるが、>>Logrotate copytruncate を使用(追加)すると、期待どおりに美しく機能します。元のファイルはゼロバイトに戻り、プログラムは書き込みを続けます。

STDOUTおよびSTDERRを回転ログファイルにリダイレクトします。

  1. some-program.sh >> /tmp/output.txt 2>&1 &
  2. /etc/logrotate.d私の場合は、output_rollと呼ばれるものの下にlogrotate構成ファイルを作成します。

    私の場合のサンプル設定:

    /tmp/output.txt {
        notifempty
        missingok
        size 1G
        copytruncate
        start 0
        rotate 15
        compress
    }
    
  3. /etc/crontabファイル内でcronジョブをセットアップします

    *  *  *  *  * root /usr/sbin/logrotate /etc/logrotate.d/output_roll
    

    これにより、ファイルが毎分チェックされます。ニーズに合わせて調整できます。

  4. 起動してください:

    $> service crond restart
    
  5. それでおしまい

注:SELinuxの設定にも問題があったSELINUX=enforcingため、に設定しましたSELINUX=disabled


1

私はこの週末にログローティーを書きました。@JdeBPのすばらしい回答とを読んだなら、おそらくそうは思わないでしょうmultilog

私はそれが軽量であり、その出力チャンクを次のようにbzip2できることに焦点を当てました。

verbosecommand | logrotee \
  --compress "bzip2 {}" --compress-suffix .bz2 \
  /var/log/verbosecommand.log

しかし、まだやるべきことがたくさんあり、テストされています。

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