วิธี จำกัด ขนาดไฟล์บันทึกโดยใช้ >>


24

ฉันจะ จำกัด ขนาดของไฟล์บันทึกที่เขียนด้วย>>200MB ได้อย่างไร

$ run_program >> myprogram.log

1
คุณต้องการให้โปรแกรมถูกฆ่าหลังจาก 200MB หรือไม่ หรือคุณต้องการ 200MB สุดท้ายกับทุกอย่างที่เก่ากว่าในที่เก็บข้อมูลบิต?
Aaron D. Marasco

ไม่กระบวนการไม่สามารถหยุดจนกว่าจะฆ่าด้วยตนเอง
david

ตัดสินใจที่จะไปเพื่อ logrotate ขอบคุณทุกคนสำหรับปัจจัยการผลิตที่มีค่า
david

คำตอบ:


9

หากแอปพลิเคชันของคุณ (เช่น. run_program) ไม่สนับสนุนการ จำกัด ขนาดของไฟล์บันทึกคุณสามารถตรวจสอบขนาดไฟล์เป็นระยะในลูปด้วยแอปพลิเคชันหรือสคริปต์ภายนอก

คุณยังสามารถใช้logrotate(8)เพื่อหมุนบันทึกของคุณมันมีsizeพารามิเตอร์ที่คุณสามารถใช้เพื่อวัตถุประสงค์ของคุณ:

ด้วยวิธีนี้ไฟล์บันทึกจะถูกหมุนเมื่อถึงขนาดที่ระบุ ขนาดอาจระบุเป็นไบต์ (ค่าเริ่มต้น), กิโลไบต์ (sizek) หรือเมกะไบต์ (sizem)


1
+1 Logfiles ที่มีข้อมูลซ้ำ ๆ กันมักจะถูกบีบอัดตามลำดับความสำคัญ
ผู้ใช้ที่ไม่รู้จัก

logrotate ตัดไฟล์หรือเพียงแค่คัดลอกหรือย้ายไฟล์ เพราะมันจะใช้งานได้หากไฟล์ที่เชื่อมโยงกับ fd ถูกตัดทอน หากเป็น mv'd ไฟล์จะยังคงเติบโตต่อไปหากไม่ได้เชื่อมโยงไฟล์จะถูกเปิดค้างไว้และจะเติบโตต่อไปจนกว่ากระบวนการจะออก ... IIRC คัดลอกไฟล์บันทึก, ยกเลิกการเชื่อมโยงและสร้างไฟล์ใหม่ ซึ่งเป็นสาเหตุที่มักส่ง SIGHUP ไปยังdæmonsเมื่อบันทึกถูกหมุน
Michael Trausch

โปรดทราบว่าแม้ว่าจะถูกตัดทอนมีปัญหาหากไฟล์ไม่ได้เปิดในโหมดต่อท้าย ( ควรเปิดไฟล์บันทึกในโหมดผนวก แต่ในประสบการณ์ของฉันมักจะไม่ได้)
Random832

Logrotate สามารถหมุนได้เมื่อไฟล์มาถึงขนาดรายวันรายสัปดาห์และอื่น ๆ นอกจากนี้ยังสามารถบีบอัดและคุณสามารถใช้postscriptตัวเลือกเพื่อให้การกำหนดค่า logrotate ส่งSIGHUPไปยังโปรแกรม
laebshade

12

ถ้าโปรแกรมของคุณไม่จำเป็นต้องเขียนไฟล์อื่น ๆ ที่จะมีขนาดใหญ่กว่าขีด จำกัด นี้คุณสามารถแจ้งเคอร์เนลของขีด จำกัด ulimitนี้โดยใช้ ก่อนที่คุณจะรันคำสั่งให้รันสิ่งนี้เพื่อตั้งค่าขีด จำกัด ขนาดไฟล์ 200MB สำหรับกระบวนการทั้งหมดที่รันในเชลล์เซสชั่นปัจจุบันของคุณ:

ulimit -f $((200*1024))

สิ่งนี้จะปกป้องระบบของคุณ แต่อาจเป็นเรื่องที่ jaring สำหรับโปรแกรมที่เขียนไฟล์ ตามที่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แทนไฟล์หากคุณมีหน่วยความจำเพียงพอ


ความคิดสร้างสรรค์ ... ที่ทิ้งไว้ในโปรแกรมว่าจะทำอย่างไรเมื่อมันหมด
Aaron D. Marasco

6

คุณสามารถตัดทอนผลลัพธ์ด้วยhead:

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

สร้างสรรค์มาก โปรดทราบว่านี่จะใช้งานได้เฉพาะเพื่อ จำกัด ข้อมูลใหม่ที่ถูกเขียนลงในไฟล์เท่านั้นโดยไม่คำนึงว่าไฟล์มีขนาดใหญ่หรือเล็กอยู่แล้ว
คาเลบ

2
โปรดทราบว่ามีความเป็นไปได้สูงที่โปรแกรมนี้จะฆ่าโปรแกรม (พร้อมSIGPIPE) เมื่อถึงขีด จำกัด ขนาดแทนที่จะทิ้งข้อมูล
Random832

1
ผมคิดคล้ายกับบางddมายากล แต่ใช่ @ Random832 ถูกต้องคุณจะได้รับSIGPIPEเป็นhead/ dd/ whateverหยดมัน
Aaron D. Marasco

ถ้าไม่สนใจมันด้วย a trap '' SIGPIPE?
tuxce

{ head -c "$size" >> log; cat > /dev/null; }หรือท่อแทน
Stéphane Chazelas

5

ในแพ็คเกจapache2-utilsเป็นยูทิลิตี้ที่เรียกว่าrotatelogsอาจเป็นประโยชน์สำหรับคุณ

สรุป:

rotatelogs [-l] [-L linkname ] [-p โปรแกรม ] [-f] [-t] [-v] [-e] [-e] [-c] [-n จำนวนไฟล์ ] logfile การหมุนเวลา | ขนาดไฟล์ (B | K | M | G) [ offset ]

ตัวอย่าง:

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

คู่มือฉบับเต็มคุณสามารถอ่านได้ที่ลิงค์นี้


ลิงก์ไม่มีอยู่
Alexander Gonchiy

1

ฉันแน่ใจว่าผู้โพสต์ดั้งเดิมได้พบวิธีการแก้ปัญหา นี่คืออีกหนึ่งสำหรับคนอื่น ๆ ที่อาจอ่านกระทู้นี้ ...

Curtail จำกัด ขนาดของเอาต์พุตของโปรแกรมและเก็บรักษาเอาต์พุต 200MB สุดท้ายด้วยคำสั่งต่อไปนี้:

$ run_program | curtail -s 200M myprogram.log

อ้างอิง

หมายเหตุ:ฉันเป็นผู้ดูแล repo ด้านบน เพียงแบ่งปันโซลูชัน ...


ฉันชอบความคิดของการลดทอน ฉันไม่คุ้นเคยกับ C ดังนั้นจึงมีโอกาสที่จะให้ไบนารีสำหรับมันได้หรือไม่ หรืออย่างน้อยคำแนะนำอย่างละเอียดเกี่ยวกับวิธีการติดตั้งหรือไม่
เฟลิเป้

0

เนื่องจากเป็นข้อความฉันจะเขียนสคริปต์ในภาษาที่คุณโปรดปรานและไพพ์ลงไป มีมันจัดการไฟล์ I / O (หรือเก็บไว้ในหน่วยความจำแล้วถ่ายโอนข้อมูลในSIGHUPหรือคล้ายกัน) สำหรับสิ่งนั้นแทนที่จะเป็น 200MB ฉันจะคิดถึงจำนวนบรรทัด 'ที่สมเหตุสมผล' เพื่อติดตาม


การเก็บข้อมูลบันทึก 200MB ไว้ในหน่วยความจำโดยไม่มีเหตุผลอื่นนอกจากจะสามารถตัดทอนมันไม่ใช่การใช้ทรัพยากรระบบที่ดีมาก และไม่ได้นับบรรทัดในไฟล์บันทึกขนาดใหญ่ ฉันจะแนะนำการใช้เครื่องมือที่สร้างขึ้นสำหรับเช่นนี้และ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

มันมีทางลัดที่เห็นได้ชัดสองอย่าง แต่โดยรวมแล้วมันก็เป็นสิ่งที่คุณต้องการ มันจะแบ่งล็อกเป็นชิ้นส่วนที่มีขนาด จำกัด และจำนวนชิ้นนั้นก็มี จำกัด เช่นกัน สามารถระบุได้ทั้งหมดผ่านอาร์กิวเมนต์บรรทัดคำสั่ง ไฟล์บันทึกจะถูกระบุด้วยบรรทัดคำสั่ง

หมายเหตุ gotcha ขนาดเล็กถ้าคุณใช้กับ daemon ที่ส้อมเป็นพื้นหลัง การใช้ไพพ์จะป้องกันไม่ให้ภูตไปที่พื้นหลัง ในกรณีนี้จะมีไวยากรณ์ (โดยเฉพาะ bash เฉพาะ) เพื่อหลีกเลี่ยงปัญหา:

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

สังเกตใน<&0ขณะที่ซ้ำซ้อนดูเหมือนว่ามันจะไม่ทำงานหากไม่มีสิ่งนี้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.