कैसे का उपयोग कर लॉग फ़ाइल का आकार सीमित करने के लिए >>


24

मैं >>200MB के साथ लिखी गई लॉग फ़ाइल के आकार को कैसे सीमित कर सकता हूं ?

$ run_program >> myprogram.log

1
क्या आप 200MB के बाद मारे गए कार्यक्रम को चाहते हैं? या क्या आप चाहते हैं कि पिछली 200MB बिट बाल्टी में पुरानी हर चीज के साथ हो?
हारून डी। मरास्को 19

नहीं, प्रक्रिया मैन्युअल रूप से मारे जाने तक रोक नहीं सकती
david

लॉगरोट के लिए जाने का फैसला किया, मूल्यवान इनपुट के लिए सभी को धन्यवाद
david

जवाबों:


9

यदि आपका एप्लिकेशन (यानी? run_program) लॉग फ़ाइल के आकार को सीमित करने का समर्थन नहीं करता है, तो आप बाह्य अनुप्रयोग या स्क्रिप्ट के साथ फ़ाइल का आकार समय-समय पर लूप में देख सकते हैं।

आप logrotate(8)अपने लॉग को घुमाने के लिए भी उपयोग कर सकते हैं , इसके sizeपैरामीटर हैं जिन्हें आप अपने उद्देश्य के लिए उपयोग कर सकते हैं:

इसके साथ, निर्दिष्ट आकार तक पहुँचने पर लॉग फ़ाइल घुमाई जाती है। आकार बाइट्स (डिफ़ॉल्ट), किलोबाइट (आकार), या मेगाबाइट (सिज़ेम) में निर्दिष्ट किया जा सकता है।


1
+1 बार-बार सूचना के साथ लॉगफ़ाइल्स अक्सर परिमाण के क्रम में संकुचित हो सकते हैं।
उपयोगकर्ता अज्ञात

क्या लॉग-इन फ़ाइलों को काटता है, या बस उन्हें कॉपी या स्थानांतरित करता है? क्योंकि यह तभी काम करेगा जब fd से जुड़ी फाइल को छोटा कर दिया जाए। यदि यह mv'd है, तो फ़ाइल आगे बढ़ती रहेगी, यदि यह अनलिंक है, तो यह केवल खुली रखी जाएगी और तब तक बढ़ती रहेगी जब तक कि यह प्रक्रिया समाप्त नहीं हो जाती ... IIRC लोगप्रोटेट कॉपी, अनलिंक और एक नई फ़ाइल बनाता है, यही कारण है कि जब उनके लॉग को घुमाया जाता है, तो अक्सर उन्हें DUPmons में SIGHUP भेजना पड़ता है।
माइकल ट्रैश जूल 22'11

ध्यान दें कि अगर यह छोटा है, तो भी एक समस्या है यदि फ़ाइल को परिशिष्ट मोड में नहीं खोला गया था (लॉग फ़ाइलें हमेशा परिशिष्ट मोड में खोली जानी चाहिए , लेकिन मेरे अनुभव में अक्सर नहीं होती हैं)
रैंडम 832

फ़ाइल, एक निश्चित आकार, दैनिक, साप्ताहिक, आदि तक पहुँच जाने के बाद, लोग रोटेट कर सकते हैं। यह संपीड़ित भी कर सकता है, और आप postscriptलॉगऑट्रेट कॉन्फ़िगरेशन SIGHUPको प्रोग्राम में भेजने के लिए विकल्प का उपयोग कर सकते हैं ।
२१:४

12

यदि आपके प्रोग्राम को ऐसी कोई अन्य फ़ाइल लिखने की आवश्यकता नहीं है, जो इस सीमा से बड़ी हो, तो आप इस सीमा के कर्नेल का उपयोग करके सूचित कर सकते हैं ulimit। अपना आदेश चलाने से पहले, अपने वर्तमान शेल सत्र में चलने वाली सभी प्रक्रिया के लिए 200MB फ़ाइल आकार सीमा सेटअप करने के लिए इसे चलाएं:

ulimit -f $((200*1024))

यह आपके सिस्टम की सुरक्षा करेगा लेकिन यह फ़ाइल लिखने वाले प्रोग्राम के लिए जेरिंग हो सकता है। जैसा कि eyazici सुझाव देता है , logrotateएक निश्चित आकार या उम्र तक पहुंचने के बाद प्रीएन लॉग फ़ाइलों की स्थापना पर विचार करें । आप पुराने डेटा को छोड़ सकते हैं या इसे संपीड़ित फ़ाइलों की एक श्रृंखला में समय के लिए संग्रहीत कर सकते हैं।


यह कार्यक्रम द्वारा लिखित किसी भी फ़ाइल के आकार को सीमित करता है
किम

सच। यदि प्रोग्राम को अन्य बड़ी फ़ाइलों को लिखने की वैध आवश्यकता थी, तो आपको एक अलग समाधान की आवश्यकता होगी।
कालेब

6

आप एक नई फाइल सिस्टम छवि बना सकते हैं, इसे लूप डिवाइस का उपयोग करके माउंट कर सकते हैं और लॉग फाइल को उस फाइल सिस्टम पर रख सकते हैं:

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यदि आपके पास पर्याप्त मेमोरी है, तो आप फ़ाइल के बजाय भी उपयोग कर सकते हैं ।


रचनात्मक विचार ... जो इसे कार्यक्रम तक छोड़ देता है जब वह बाहर निकलता है तो क्या करना है।
आरोन डी। मारास्को जू

6

आप इसके साथ आउटपुट को छोटा कर सकते हैं head:

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

बहुत रचनात्मक। बस ध्यान दें कि यह केवल फ़ाइल में लिखे जा रहे नए डेटा को सीमित करने के लिए काम करेगा, यह ध्यान नहीं रखेगा कि फ़ाइल पहले से कितनी बड़ी या छोटी थी।
कालेब

2
ध्यान दें कि यह संभावना है कि यह प्रोग्राम (के साथ SIGPIPE) को मार देगा , क्योंकि यह डेटा को छोड़ने के बजाय आकार सीमा तक पहुंच गया है।
रैंडम 832

1
मैं कुछ के साथ इसी तरह सोच रहा था ddजादू लेकिन हाँ @ Random832 सही है, तो आप एक मिल जाएगा SIGPIPEके रूप में head/ dd/ whateverयह चला जाता है।
आरोन डी। मरास्को जू

एक के साथ इसे अनदेखा करने के बारे में क्या trap '' SIGPIPE?
tuxce

या इसके बजाय पाइप { head -c "$size" >> log; cat > /dev/null; }
स्टीफन चेजलस

5

पैकेज apache2-utilsमें वर्तमान उपयोगिता कहा जाता है rotatelogs, यह आपके लिए उपयोगी हो सकता है।

सारांश:

rotatelogs [-l] [एल linkname ] [-p कार्यक्रम ] [-f] [आयकर] [-v] [-e] [-c] [-n संख्या के- फ़ाइलें ] लॉगफ़ाइल rotationtime | filesize (B | K | M | G) [ ऑफसेट ]

उदाहरण:

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

पूर्ण मैनुअल आप इस लिंक पर पढ़ सकते हैं ।


लिंक कुछ भी नहीं है।
अलेक्जेंडर गोंचि

1

मुझे यकीन है कि मूल पोस्टर ने एक समाधान ढूंढ लिया है। यहां अन्य लोगों के लिए एक और है जो इस धागे को पढ़ सकता है ...

कर्टेल एक प्रोग्राम के आउटपुट के आकार को सीमित करता है और अंतिम कमांड के साथ अंतिम 200MB आउटपुट को संरक्षित करता है:

$ run_program | curtail -s 200M myprogram.log

संदर्भ

नोट: मैं उपरोक्त रेपो का अनुचर हूं। बस समाधान साझा कर रहा हूं ...


मुझे कर्ल का विचार पसंद है। मैं C से उतना परिचित नहीं हूं, इसलिए इसके लिए एक बाइनरी प्रदान करने का मौका है? या इसे स्थापित करने के बारे में कम से कम विस्तृत निर्देश?
फेलिप

0

चूंकि यह पाठ है, इसलिए मैं आपकी पसंदीदा भाषा में एक स्क्रिप्ट लिखूंगा और उसे उस पर पाइप करूंगा। क्या यह फ़ाइल I / O को संभालती है (या इसे सभी मेमोरी में रखें और फिर इसे SIGHUPया इसी तरह डंप करें )। उसके लिए, 200MB के बजाय, मैं ट्रैक करने के लिए लाइनों की एक 'उचित' संख्या के बारे में सोचूंगा।


200 एमबी लॉग डेटा को स्मृति में रखने के अलावा किसी अन्य कारण से यह सिस्टम संसाधनों का बहुत अच्छा उपयोग नहीं कर सकता है। न ही एक बड़ी लॉग फ़ाइल पर एक पंक्ति गणना कर रहा है। मैं इस तरह syslogऔर इसके लिए निर्मित उपकरणों का उपयोग करने की सलाह दूंगा logrotate
कालेब

0

निम्नलिखित स्क्रिप्ट को काम करना चाहिए।

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

इसमें स्पष्ट शॉर्ट-कट की एक जोड़ी है, लेकिन कुल मिलाकर यह वही करता है जो आपने पूछा था। यह लॉग को एक सीमित आकार के विखंडू में विभाजित करेगा, और विखंडू की मात्रा भी सीमित है। सभी को कमांड-लाइन तर्कों के माध्यम से निर्दिष्ट किया जा सकता है। लॉग फ़ाइल को कमांड लाइन के माध्यम से भी निर्दिष्ट किया गया है।

यदि आप इसे डेमॉन के साथ उपयोग करते हैं, जो पृष्ठभूमि में कांटे हैं, तो एक छोटे गोच पर ध्यान दें। एक पाइप का उपयोग डेमॉन को पृष्ठभूमि पर जाने से रोक देगा। इस मामले में समस्या से बचने के लिए (संभावित बाश-विशिष्ट) सिंटैक्स है:

my_daemon | ( logger.sh /var/log/my_log.log <&0 & )

ध्यान दें <&0, जबकि अनावश्यक रूप से, यह इसके बिना काम नहीं करेगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.