>>を使用してログファイルのサイズを制限する方法


24

書き込まれるログファイルのサイズ>>を200MB に制限するにはどうすればよいですか?

$ run_program >> myprogram.log

1
200MB後にプログラムを強制終了しますか?それとも、ビットバケット内の古いものすべてを含む最後の200MBが必要ですか?
アーロンD.マラスコ

手動で殺されるまで、いや、プロセスが停止することはできません
デビッド・

貴重な入力のおかげでみんな、logrotateのために行くことにしました
デイヴィッド

回答:


9

アプリケーション(つまり、run_program)がログファイルのサイズ制限をサポートしていない場合、外部アプリケーションまたはスクリプトを使用してループで定期的にファイルサイズを確認できます。

またlogrotate(8)、ログのローテーションにも使用sizeできます。目的に使用できるパラメーターがあります。

これにより、指定したサイズに達するとログファイルがローテーションされます。サイズは、バイト(デフォルト)、キロバイト(sizek)、またはメガバイト(sizem)で指定できます。


1
+1情報が繰り返される+1ログファイルは、しばしば桁違いに圧縮される可能性があります。
ユーザー不明

logrotateはファイルを切り捨てますか、それとも単にコピーまたは移動しますか?これは、fdに関連付けられたファイルが切り捨てられた場合にのみ機能するためです。mv'dの場合、ファイルは拡大し続けます。unlink 'の場合、ファイルは開いたままになり、プロセスが終了するまで拡大し続けます... IIRC logrotateコピー、リンク解除、および新しいファイルの作成、そのため、ログがローテーションされたときに、SIGHUPをデーモンに頻繁に送信する必要があります。
マイケルトラウシュ

切り捨てられたとしても、ファイルが追加モードで開かれていない場合は問題があることに注意してください(ログファイル常に追加モードで開かれるべきですが、私の経験ではそうではないことが多いです)
Random832

Logrotateは、ファイルが特定のサイズ(毎日、毎週など)に達するとローテーションできます。また、圧縮することもできます。logrotateconfigをプログラムにpostscript送信するオプションを使用できますSIGHUP
-laebshade

12

プログラムがこの制限よりも大きいその他のファイルを書き込む必要がない場合は、を使用してこの制限をカーネルに通知できますulimit。コマンドを実行する前に、これを実行して、現在のシェルセッションで実行されるすべてのプロセスに対して200MBのファイルサイズ制限を設定します。

ulimit -f $((200*1024))

これはシステムを保護しますが、ファイルを作成するプログラムにとっては不快な場合があります。以下のようeyaziciが示唆、設定を検討logrotate彼らは、特定のサイズや年齢に達するとプルーンのログファイルに。古いデータを破棄するか、一連の圧縮ファイルで一定期間アーカイブすることができます。


これは、サイズ制限の任意のプログラムによって書かれたファイル
キム・

本当です。プログラムに他の大きなファイルを書き込む正当なニーズがある場合、別のソリューションが必要になります。
カレブ

6

新しいファイルシステムイメージを作成し、ループデバイスを使用してマウントし、そのファイルシステムにログファイルを置くことができます。

dd if=/dev/zero of=./200mb.img bs=1024 count=200000 # create new empty 200MB file
mkfs.ext2 200mb.img # or ext3, or whatever fits your needs
mkdir logs
sudo mount -t ext2 -o loop 200mb.img logs # only root can do '-o loop' by default
run_program >>logs/myprogram.log

tmpfs十分なメモリがある場合は、ファイルの代わりに使用することもできます。


独創的なアイデア...それはそれがなくなったときに何をするかについてはプログラムに任せます。
アーロンD.マラスコ

6

以下を使用して出力を切り捨てることができますhead

size=$((200*1024*1024-$(stat -c %s myprogram.log)))
run_program | head -c ${size} >> myprogram.log

非常に創造的です。これは、ファイルに書き込まれる新しいデータを制限するためにのみ機能することに注意してください。ファイルがすでにどれだけ大きいか小さいかは考慮されません。
カレブ

2
これはSIGPIPE、データを破棄するのではなく、サイズ制限に達するとプログラムを(withで)強​​制終了する可能性が高いことに注意してください。
ランダム832

1
私はいくつかのと同様のことを考えていたdd魔法が、ええ@ Random832は右である、あなたが買ってあげるSIGPIPEhead/ dd/がwhateverそれをドロップ。
アーロンD.マラスコ

でそれを無視するのはtrap '' SIGPIPEどうですか?
タキシード

または、代わりににパイプし{ head -c "$size" >> log; cat > /dev/null; }ます。
ステファンシャゼル

5

パッケージにapache2-utilsrotatelogs、と呼ばれる現在のユーティリティがあります。

あらすじ:

rotatelogs [-l] [-L linkname ] [-p program ] [-f] [-t] [-v] [-e] [-c] [-n ファイル数 ] logfile rotationtime | ファイルサイズ(B | K | M | G)[ オフセット ]

例:

your_program | rotatelogs -n 5 /var/log/logfile 1M

このリンクで読むことができる完全なマニュアル。


リンクが存在しません。
アレクサンダーゴンチー

1

元のポスターが解決策を見つけたと確信しています。このスレッドを読む可能性のある他の人のための別のものがあります...

Curtailは、プログラムの出力のサイズを制限し、次のコマンドで最後の200MBの出力を保持します。

$ run_program | curtail -s 200M myprogram.log

参照資料

注:私は上記のリポジトリの管理者です。ソリューションを共有するだけです...


削減のアイデアが大好きです。私はCにあまり詳しくないので、バイナリを提供する機会はありますか?または少なくともそれをインストールする方法の詳細な手順は?
フェリペ

0

それはテキストなので、私はあなたの好きな言語でスクリプトを書き、それにパイプします。ファイルI / Oを処理します(または、すべてをメモリに保存してから、ダンプするSIGHUPか、類似したものにします)。そのために、200MBではなく、「合理的な」数の行を追跡することを考えます。


200 MBのログデータを切り捨てられる以外の理由でメモリに保持することは、システムリソースのあまり有効な使用ではありません。また、大きなログファイルで行カウントを行っていません。私はこのようなのために構築されたツールで使用することをお勧めしますsyslogとをlogrotate
カレブ

0

次のスクリプトがジョブを実行するはずです。

LOG_SIZE=500000
NUM_SEGM=2
while getopts "s:n:" opt; do
  case "$opt" in
    s)
      LOG_SIZE=$OPTARG
      ;;
    n)
      NUM_SEGM=$OPTARG
      ;;
  esac
done
shift $((OPTIND-1))
if [ $# == 0 -o -z "$1" ]; then
    echo "missing output file argument"
    exit 1
fi
OUT_FILE=$1
shift
NUM=1
while :; do
    dd bs=10 count=$(($LOG_SIZE/10)) >> $OUT_FILE 2>/dev/null
    SZ=`stat -c%s $OUT_FILE`
    if [ $SZ -eq 0 ]; then
        rm $OUT_FILE
        break
    fi
    echo -e "\nLog portion finished" >> $OUT_FILE
    mv $OUT_FILE $OUT_FILE.n$NUM
    NUM=$(($NUM + 1))
    [ $NUM -gt $NUM_SEGM ] && NUM=1
done

いくつかの明らかなショートカットがありますが、全体的にはあなたが求めたものを実行します。ログを制限されたサイズのチャンクに分割し、チャンクの量も制限されます。すべては、コマンドライン引数を介して指定できます。ログファイルもコマンドラインで指定します。

バックグラウンドに分岐するデーモンで使用する場合は、小さな落とし穴に注意してください。パイプを使用すると、デーモンがバックグラウンドに移行できなくなります。この場合、問題を回避する(おそらくbash固有の)構文があります。

my_daemon | ( logger.sh /var/log/my_log.log <&0 & )

に注意してください、<&0一見冗長ですが、これなしでは動作しません。

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