>>
で書き込まれたログファイルのサイズを200MBに制限するにはどうすればよいですか?
$ run_program >> myprogram.log
アプリケーション(つまり、_run_program
_)がログファイルのサイズの制限をサポートしていない場合は、外部アプリケーションまたはスクリプトを使用してループで定期的にファイルサイズを確認できます。
logrotate(8)
を使用してログをローテーションすることもできます。これには、目的に使用できるsize
パラメータがあります。
これにより、指定したサイズに達するとログファイルがローテーションされます。サイズは、バイト(デフォルト)、キロバイト(sizek)、またはメガバイト(sizem)で指定できます。
プログラムがこの制限よりも大きい他のファイルを書き込む必要がない場合は、ulimit
を使用してカーネルにこの制限を通知できます。コマンドを実行する前に、次のコマンドを実行して、現在のシェルセッションで実行されるすべてのプロセスに200MBのファイルサイズ制限を設定します。
ulimit -f $((200*1024))
これはシステムを保護しますが、ファイルを書き込むプログラムにとって不快になる可能性があります。 eyaziciの提案 のように、特定のサイズまたは経過時間に達したら、logrotate
をPruneログファイルに設定することを検討してください。古いデータを破棄するか、一連の圧縮ファイルに一定期間アーカイブすることができます。
head
で出力を切り捨てることができます:
size=$((200*1024*1024-$(stat -c %s myprogram.log)))
run_program | head -c ${size} >> myprogram.log
新しいファイルシステムイメージを作成し、ループデバイスを使用してそれをマウントし、ログファイルをそのファイルシステムに置くことができます。
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
を使用することもできます。
パッケージApache2-utils
はrotatelogs
と呼ばれる現在のユーティリティであり、役立つ場合があります。
あらすじ:
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
このリンク で読むことができる完全なマニュアル。
オリジナルのポスターが解決策を見つけたと私は確信しています。これは、このスレッドを読む可能性がある他の人のための別のものです...
次のコマンドを使用すると、プログラムの出力のサイズが制限され、最後の200MBの出力が保持されます。
$ run_program | curtail -s 200M myprogram.log
注:私は上記のリポジトリのメンテナーです。ソリューションを共有するだけ...
次のスクリプトがその仕事をするはずです。
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
、一見冗長に見えますが、これなしでは機能しません。
テキストなので、好きな言語でスクリプトを書いて、それにパイプします。ファイルI/Oを処理します(またはすべてをメモリに保持してから、SIGHUP
にダンプします)。そのため、200MBの代わりに、追跡する「妥当な」行数を考えます。