web-dev-qa-db-ja.com

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

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

$ run_program >> myprogram.log
26
david

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

logrotate(8) を使用してログをローテーションすることもできます。これには、目的に使用できるsizeパラメータがあります。

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

10
Emre Yazici

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

ulimit -f $((200*1024))

これはシステムを保護しますが、ファイルを書き込むプログラムにとって不快になる可能性があります。 eyaziciの提案 のように、特定のサイズまたは経過時間に達したら、logrotateをPruneログファイルに設定することを検討してください。古いデータを破棄するか、一連の圧縮ファイルに一定期間アーカイブすることができます。

12
Caleb

headで出力を切り捨てることができます:

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

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

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を使用することもできます。

5
alex

パッケージApache2-utilsrotatelogsと呼ばれる現在のユーティリティであり、役立つ場合があります。

あらすじ:

rotatelogs [-l] [-Llinkname] [-pprogram ] [-f] [-t] [-v] [-e] [-c] [-nnumber-of-files]ログファイルrotationtime|filesize(B | K | M | G)[offset]

例:

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

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

5
PRIHLOP

オリジナルのポスターが解決策を見つけたと私は確信しています。これは、このスレッドを読む可能性がある他の人のための別のものです...

次のコマンドを使用すると、プログラムの出力のサイズが制限され、最後の200MBの出力が保持されます。

$ run_program | curtail -s 200M myprogram.log

参考文献

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

1
Dave Wolaver

次のスクリプトがその仕事をするはずです。

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、一見冗長に見えますが、これなしでは機能しません。

0
stsp

テキストなので、好きな言語でスクリプトを書いて、それにパイプします。ファイルI/Oを処理します(またはすべてをメモリに保持してから、SIGHUPにダンプします)。そのため、200MBの代わりに、追跡する「妥当な」行数を考えます。

0