web-dev-qa-db-ja.com

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

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

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

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

logrotateプログラムについて説明するいくつかの回答を見てきましたが、それは良いように聞こえますが、ログファイルを内部で生成し、HUP信号を処理するプログラムにも焦点を当てているようです。これを基本的な出力リダイレクトスクリプトで機能させる方法はありますか?

56
Miral

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

  • Dan Bernsteinの multilog daemontoolsから
  • Bruce Guenterの multilog daemontools-encoreから
  • ローランベルコット s6-log s6から
  • Gerrit Pape's svlogd runitから
  • ウェインマーシャルの tinylog perpから
  • cyclognosh から

次に、multilog形式のログファイルセットを処理するツールには、次のものがあります。

参考文献

48
JdeBP

apacheに同梱されているrotatelogsツール(bin dir内)( docs を参照)は、stdinから入力を受け取り、特定の時間が経過するとログをローテーションします

16
BertNase

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

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

それ以外の場合は、ログに記録したコンテンツをカスタムプログラムまたはスクリプトにパイプして処理するか、 logrotate 構成の設定を確認することをお勧めします。

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

14
Lara Dougan

私は同様の問題を抱えていて、最初にlogrotateを破棄しましたが、logrotateが実際にこれをうまく実行できることがわかりました。重要なディレクティブは "copytruncate"です。何らかの理由で、この用語が私が行ったグーグルのいずれにも当てはまらなかったため、この回答を追加して、このケースでどのように使用するかを明確にします。

トリックはこれが機能するのはリダイレクトが ">>"(append)ではなく "> "(作成)。

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

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

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

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

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

logrotate truncate.cfg
14
Sam Hendley

私のユースケースではmultilogが好きですが、私のユースケースは非常に単純でシンプルなので、見つけたdocs/examplesに単純に配置されていません。以下はシンプルなマルチログ回転の例です:

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

いくつかのメモ:

  • これは/ tmp/myapp /ディレクトリにログをダンプします
  • s10000は10,000バイトを表します*
  • n5は5つのファイルを表します。*「現在の」ログはファイルの1つとして数えられるため、これには4つの古いログ+「現在の」ログが含まれます
  • これは、フランソワボーソレイユが次のURLで提供した例に基づいており、それに基づいています。 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 &

そのコマンドはあなたを始めるでしょう。

3
sage

Splitを使用してください。これはcoreutilsの一部です。 stdinを受け取ってチャンクに分割できます(チャンクサイズや行数などに基づく)。

例:

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

ダッシュ(-)は、ファイルの代わりに標準入力を使用するように「分割」に指示することに注意してください。

3
Nazar

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

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

状況によっては、1つの警告が問題になる場合と問題にならない場合があります。

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

事例として、ユーザーがこのディレクティブを適用することを奨励する「現実の」ログソースをいくつか見ました。このオプションについては、いくつかの議論があります here

3
natevw

上記のサムヘンドリーのコメントに追加したいと思います。

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

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

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

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

    私のケースのサンプル設定:

    /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
user578558

logrotee を今週末に書きました。 @JdeBPの素晴らしい答えとmultilogを読んだら、おそらく私はそうは思わないでしょう。

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

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

ただし、まだ完了していないことがたくさんあります。

1

ここにリストされているツールに完全に満足していないため、log_proxyと呼ばれる別のツール(申し訳ありません!)を作成しました。

主な特徴:

  • パイプとして使用可能(myapp myapp_arg1 myapp_arg2 |log_proxy /log/myapp.log
  • 構成可能なログローテーションサフィックスとstftimeプレースホルダー(例:.%Y%m%d%H%M%S
  • ローテーションされたファイルの数を制限できます(最も古いファイルを削除します)
  • ファイルのサイズ(バイト単位)に応じてファイルをローテーションできます
  • 経過時間(秒単位)に応じてファイルをローテーションできます
  • 特定のアプリに特定のログディレクトリを必要としません(1つのディレクトリに、さまざまなアプリのさまざまなログファイルを多数含めることができます)
  • 同じアプリの複数のインスタンスが問題なく同じファイルにログを記録できます(例:myapp arg1 |log_proxy --use-locks /log/myapp.logmyapp arg2 |log_proxy --use-locks /log/myapp.logは同時に実行できます)
  • cで実装されている(高速で多くのメモリを消費しない)
  • cLIオプションと環境変数で構成可能
  • stdoutおよびstderrをキャプチャするラッパーとして使用可能(log_proxy_wrapper --stdout=/log/myapp.stdout --stderr=/log/myapp.stderr -- myapp myapp_arg1 myapp_arg2
  • CentOS 6(2011!)のような非常に古いディストリビューションであっても、依存関係のないバイナリリリース

コメント、問題、PRを歓迎します: https://github.com/metwork-framework/log_proxy

0
Fabien