Günlük dosyası boyutunu >> kullanarak nasıl sınırlandırılır


24

Yazılan bir günlük dosyasının boyutunu >>200 MB ile nasıl sınırlayabilirim ?

$ run_program >> myprogram.log

1
Programın 200 MB’dan sonra ölmesini istiyor musunuz? Yoksa son 200 MB'lık bit kovadaki daha eski her şeyi mi istiyorsun?
Aaron D. Marasco,

hayır, süreç el ile öldürülene kadar
david

logrotate için gitmeye karar verdi, değerli girdiler için herkese teşekkürler
david

Yanıtlar:


9

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.


1
+1 Tekrarlanan bilgileri içeren günlük dosyaları genellikle büyüklük derecelerinde sıkıştırılabilir.
kullanıcı bilinmeyen

Logrotate, dosyaları keser mi, yoksa basitçe kopyalar veya taşır mı? Çünkü bu, yalnızca fd ile ilişkilendirilmiş dosya kesildiğinde çalışacaktır. Mv'd ise dosya büyümeye devam edecek, eğer bağlantısı kesilirse, işlem devam edilinceye kadar sadece açık tutulacak ve büyümeye devam edecektir ... bu yüzden kişi günlükleri döndürüldüğünde dæmons'a SIGHUP göndermek zorunda kalıyor.
Michael Trausch

Kısaltılacak olsa bile dosya Ekleme modunda açılmış olmasaydı, bir sorun var Not (günlük dosyaları gerektiğini hep Ekleme modunda açılmış, ama benim deneyim olması genellikle değildir)
Random832

Günlük, haftalık, vb. Belirli bir boyuta ulaştığında logrotate dönebilir. Ayrıca sıkıştırabilir ve postscriptlogrotate config'in SIGHUPprograma göndermesini sağlamak için bu seçeneği kullanabilirsiniz .
laebshade

12

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.


Bu program tarafından yazılmış herhangi bir dosyanın boyutunu sınırlar
Kim

Doğru. Programın başka büyük dosyalar yazmak için yasal bir ihtiyacı varsa, farklı bir çözüme ihtiyacınız olacaktır.
Caleb,

6

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 .


Yaratıcı fikir ... bu, bittiğinde ne yapılması gerektiği konusunda onu programa bırakıyor.
Aaron D. Marasco,

6

Çıktıyı aşağıdaki şekilde kesebilirsiniz head:

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

Çok yaratıcı. Bunun sadece dosyaya yazılan YENİ verileri sınırlandırmak için işe yarayacağına dair bir not, dosyanın zaten ne kadar büyük ya da küçük olduğunu dikkate almaz.
Caleb,

2
SIGPIPEVerileri silmek yerine, boyut sınırına ulaştıktan sonra programın (birlikte ) öldürülmesinin olası olduğunu unutmayın .
Random832

1
Bazı benzer düşünüyordum ddbüyü ama evet @ Random832 haklı, bir alırsınız SIGPIPEolarak head/ dd/ whateverit düşer.
Aaron D. Marasco,

Peki ya bunu görmezden gelmeye trap '' SIGPIPE?
smokin

Veya yerine boru { head -c "$size" >> log; cat > /dev/null; }.
Stéphane Chazelas

5

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 .


Bağlantı mevcut değil.
Alexander Gonchiy

1

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

Referanslar

NOT: Ben yukarıdaki deponun sahibiyim. Sadece çözümü paylaşıyoruz ...


Kıvrılma fikrini seviyorum. C'ye aşina değilim, bu yüzden bunun için bir ikili dosya sağlama şansı var mı? veya en azından nasıl kurulacağına dair ayrıntılı talimatlar?
Felipe

0

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.


200 MB'lık log verisini, kısaltmaktan başka bir sebep olmadan bellekte tutmak, sistem kaynaklarını çok iyi kullanmaz. Büyük bir kütük dosyasında satır sayımı da yapmıyor. Bunun için oluşturulmuş araçları kullanmanızı tavsiye ederim syslogve logrotate.
Caleb

0

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.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.