Logrotateは開いたファイルを切り捨てません。

Logrotateは開いたファイルを切り捨てません。

テストとデモの両方のプラットフォームの役割を実行するシステムがあります。システムから出力される多くのデータを記録していますが、ログファイルがすぐに埋められ、最終的にハードドライブのパーティションスペースをすべて使用することになりますので、配布するときは記録しません。

試してみましたlogrotateが、プログラムが実行されていない場合にのみ機能するようです。プログラムが閉じたら、ファイルを正しく切り取り、圧縮されたバージョンを記録し、残りを削除します。ただし、ログファイルを入力するプログラムが実行されている場合、圧縮ファイルは正しく生成されますが、アクティブファイルは切り捨てられません。どのように切り取るかを調べようとします。

単純なリダイレクトを介してログファイルに書き込みます。 ProgramA>logAなどprogramB>logB私のプログラムは入力ベクトルを受け取るたびに出力するので、出力は非常に高速です。私の仮定は、フィールドへの継続的な書き込みのためにログロテートが切り捨てられないことです。しかし、これが理由であることを確認できる人はいますか?

logrotateはエラーファイルを正確にどこに保存しますか?

また:logrotateの動作を修正したいと思います。有効になって100MBなどの大容量ログファイルが表示されたら、コピーを作成したいと思います。ただ元のログファイルを切り捨てる前に、ファイルの最後の1MBを削除します(ファイルの古い99MBのコンテンツを削除します)。最新のデータを維持する必要がありますが、非常に古いデータはあまり気にしません。誰でもこれを行う方法を教えてもらえますか?

答え1

私はこれが少し古いことを知っていますが、同じ問題があり、解決策は出力ファイルを破壊するのではなく、出力ファイルに追加のリダイレクトを使用することでした。これにより、アプリケーション/スクリプトはファイルを排他的にロックしません。

変える:

ProgramA > logA

使用:

ProgramA >> logA 

挨拶。

答え2

からman logrotate

   copytruncate
          Truncate the original log file to zero size in place after creat‐
          ing a copy, instead of moving the old  log  file  and  optionally
          creating  a  new one.  It can be used when some program cannot be
          told to  close  its  logfile  and  thus  might  continue  writing
          (appending) to the previous log file forever.  Note that there is
          a very small time slice between copying the file  and  truncating
          it,  so  some  logging  data  might be lost.  When this option is
          used, the create option will have no effect, as the old log  file
          stays in place.

これは構成ファイルに入れる必要があるオプションです。

その他の質問について:postrotateディレクティブを使用してファイルを回転させ、切り捨てコマンドを実行します。この場合、切り捨てた後、このステップで手動で圧縮する必要があります。logrotate(実際には、最初のアーカイブが圧縮されていないため、最後の部分ではありません。)

編集する:最後の1MBの維持について詳しくはこちらをご覧ください。ログファイルが200Kを超える場合は、置き換えて5つのバックアップのみを維持するように設定できます。これにより、常に最後の1MB程度を維持します。最初のバックアップが大きすぎる場合は、5つのバックアップが完了して「落ちる」まで待つことができます。

答え3

約束どおり、Perlの数行で書かれた「十分に近い」リングバッファプログラムです。

これを使用するには、必要なログファイルのサイズ(バイト単位)と2つ以上のログファイルを渡します。 Xバイトごとにログファイルを切り替えます。すでにこのようなプログラムがあると確信していますが、クイック検索では見つけることができません。例えば、

$ your-app | log-splitter 1048576 /var/log/your-app/log1 /var/log/your-app/log2

もちろん、ファイルがlog-splitter$ PATHで実行可能であり、次のものが含まれているとします。

#!/usr/bin/perl
use warnings qw(all);
use strict;
use autodie;
use Carp;
use Fcntl qw(SEEK_SET);
use IO::Handle;

# yes, we truncate all logs at start. Sorry.
@ARGV >= 2 or croak "Usage: $0 log-size log-file...";
my ($max_size, @lognames) = @ARGV;
my @logs = map {
    open my $fh, '+>', $_;
    $fh->autoflush(1);
    $fh;
} @lognames;

my $current_size = $max_size;
my $current_log  = $#logs;
while (defined(my $line = <STDIN>)) {
    if ($current_size >= $max_size) {
        $current_log  = ($current_log + 1) % @logs;
        $current_size = 0;
        seek($logs[$current_log], 0, SEEK_SET);
        truncate($logs[$current_log], 0);
    }

    $current_size += length($line);
    print {$logs[$current_log]} $line;
}

close($_) foreach @logs;

このコードに関連するライセンスの問題を明確にするには、次の手順を実行します。

CC0
法律が許す限り、Anthony DeRobertisは上記のプログラム(ログスプリッター)に対するすべての著作権および関連する権利または著作権を放棄します。この作品の出版場所:アメリカ。

関連情報