回答:
アプリケーション(つまり、run_program
)がログファイルのサイズ制限をサポートしていない場合、外部アプリケーションまたはスクリプトを使用してループで定期的にファイルサイズを確認できます。
またlogrotate(8)
、ログのローテーションにも使用size
できます。目的に使用できるパラメーターがあります。
これにより、指定したサイズに達するとログファイルがローテーションされます。サイズは、バイト(デフォルト)、キロバイト(sizek)、またはメガバイト(sizem)で指定できます。
postscript
送信するオプションを使用できますSIGHUP
。
プログラムがこの制限よりも大きいその他のファイルを書き込む必要がない場合は、を使用してこの制限をカーネルに通知できますulimit
。コマンドを実行する前に、これを実行して、現在のシェルセッションで実行されるすべてのプロセスに対して200MBのファイルサイズ制限を設定します。
ulimit -f $((200*1024))
これはシステムを保護しますが、ファイルを作成するプログラムにとっては不快な場合があります。以下のようeyaziciが示唆、設定を検討logrotate
彼らは、特定のサイズや年齢に達するとプルーンのログファイルに。古いデータを破棄するか、一連の圧縮ファイルで一定期間アーカイブすることができます。
新しいファイルシステムイメージを作成し、ループデバイスを使用してマウントし、そのファイルシステムにログファイルを置くことができます。
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
十分なメモリがある場合は、ファイルの代わりに使用することもできます。
以下を使用して出力を切り捨てることができますhead
。
size=$((200*1024*1024-$(stat -c %s myprogram.log)))
run_program | head -c ${size} >> myprogram.log
SIGPIPE
、データを破棄するのではなく、サイズ制限に達するとプログラムを(withで)強制終了する可能性が高いことに注意してください。
dd
魔法が、ええ@ Random832は右である、あなたが買ってあげるSIGPIPE
とhead
/ dd
/がwhatever
それをドロップ。
trap '' SIGPIPE
どうですか?
{ head -c "$size" >> log; cat > /dev/null; }
ます。
パッケージにapache2-utils
はrotatelogs
、と呼ばれる現在のユーティリティがあります。
あらすじ:
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
このリンクで読むことができる完全なマニュアル。
元のポスターが解決策を見つけたと確信しています。このスレッドを読む可能性のある他の人のための別のものがあります...
Curtailは、プログラムの出力のサイズを制限し、次のコマンドで最後の200MBの出力を保持します。
$ run_program | curtail -s 200M myprogram.log
注:私は上記のリポジトリの管理者です。ソリューションを共有するだけです...
それはテキストなので、私はあなたの好きな言語でスクリプトを書き、それにパイプします。ファイルI / Oを処理します(または、すべてをメモリに保存してから、ダンプするSIGHUP
か、類似したものにします)。そのために、200MBではなく、「合理的な」数の行を追跡することを考えます。
syslog
とをlogrotate
。
次のスクリプトがジョブを実行するはずです。
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
一見冗長ですが、これなしでは動作しません。