Yazılan bir günlük dosyasının boyutunu >>200 MB ile nasıl sınırlayabilirim ?
$ run_program >> myprogram.log
Yazılan bir günlük dosyasının boyutunu >>200 MB ile nasıl sınırlayabilirim ?
$ run_program >> myprogram.log
Yanıtlar:
Uygulamanız (örn. run_program) Günlük dosyasının boyutunu sınırlamayı desteklemiyorsa, dosya boyutunu düzenli olarak harici bir uygulama veya komut dosyası içeren bir döngüde kontrol edebilirsiniz.
logrotate(8)Günlüklerinizi döndürmek için de kullanabilirsiniz size, amacınız için kullanabileceğiniz parametreye sahiptir:
Bununla, belirtilen boyuta ulaşıldığında günlük dosyası döndürülür. Boyut, bayt (varsayılan), kilobayt (sizek) veya megabayt (sizem) olarak belirtilebilir.
postscriptlogrotate config'in SIGHUPprograma göndermesini sağlamak için bu seçeneği kullanabilirsiniz .
Programınızın bu sınırdan daha büyük herhangi bir DİĞER dosya yazması gerekmiyorsa, bu sınırın çekirdeğini kullanarak bilgi verebilirsiniz ulimit. Komutunuzu çalıştırmadan önce, mevcut kabuk oturumunuzdaki tüm işlemlerde 200 MB'lık bir dosya boyutu sınırı belirlemek için bunu çalıştırın:
ulimit -f $((200*1024))
Bu sisteminizi koruyacaktır ancak dosyayı yazan program için tehlikeli olabilir. Gibi eyazici anlaşılacağı ayarlamayı düşünmelisiniz logrotatebelli bir boyut veya yaşına geldikleri zaman erik günlük dosyalarına. Eski verileri atabilir veya bir dizi sıkıştırılmış dosyada bir süre arşivleyebilirsiniz.
Yeni bir dosya sistemi görüntüsü oluşturabilir, loop cihazını kullanarak bağlayabilir ve günlük dosyasını bu dosya sistemine koyabilirsiniz:
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
tmpfsYeterli belleğiniz varsa, bir dosya yerine de kullanabilirsiniz .
Çıktıyı aşağıdaki şekilde kesebilirsiniz head:
size=$((200*1024*1024-$(stat -c %s myprogram.log)))
run_program | head -c ${size} >> myprogram.log
SIGPIPEVerileri silmek yerine, boyut sınırına ulaştıktan sonra programın (birlikte ) öldürülmesinin olası olduğunu unutmayın .
ddbüyü ama evet @ Random832 haklı, bir alırsınız SIGPIPEolarak head/ dd/ whateverit düşer.
trap '' SIGPIPE?
{ head -c "$size" >> log; cat > /dev/null; }.
Pakette apache2-utilsadı verilen yardımcı program var rotatelogs, sizin için yararlı olabilir.
Özet:
rotatelogs [-l] [L bağlantıadı ] [-p Program ] [-f] [-t] [-v] [e] [-c] [-n sayı-of-files ] günlük dosyası saat_farkı | dosya boyutu (B | K | M | G) [ uzaklık ]
Örnek:
your_program | rotatelogs -n 5 /var/log/logfile 1M
Kılavuzun tamamını bu linkten okuyabilirsiniz .
Orijinal posterin bir çözüm bulduğuna eminim. İşte bu konuyu okuyabilenler için başka bir tane daha ...
Curtail, bir programın çıktısının boyutunu sınırlar ve aşağıdaki komut ile son 200 MB çıktısını korur:
$ run_program | curtail -s 200M myprogram.log
NOT: Ben yukarıdaki deponun sahibiyim. Sadece çözümü paylaşıyoruz ...
Metin olduğu için en sevdiğiniz dilde bir senaryo yazar ve yazı yazarım. Dosyayı G / Ç ile işlemesini sağlayın (veya hepsini bellekte tutun ve sonra üzerine SIGHUPya da benzeri bir yere bırakın ). Bunun için 200 MB yerine, takip edilmesi gereken 'makul' bir satır sayısını düşünecektim.
syslogve logrotate.
Aşağıdaki komut dosyası işi yapmalı.
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
Birkaç açık kısayol var, ancak genel olarak istediğinizi yapar. Günlüğü, sınırlı büyüklükteki bir parçaya böler ve topakların miktarı da sınırlıdır. Hepsi komut satırı argümanları ile belirtilebilir. Günlük dosyası da komut satırı üzerinden belirtilir.
Arka planda çatal olan cini ile kullanıyorsanız küçük bir yakaladığınızı unutmayın. Bir boru kullanmak, arka planın arka plana gitmesini önler. Bu durumda, sorunu önlemek için (bash'a özgü) bir sözdizimi vardır:
my_daemon | ( logger.sh /var/log/my_log.log <&0 & )
Unutmayın, <&0görünüşte gereksiz olsa da, bu olmadan çalışmayacak.