เข้าสู่ระบบการหมุนของ stdout?


53

ฉันมีโปรแกรม Linux ที่สามารถเขียนข้อมูลไปยัง stdout และ stderr

/var/logฉันมีสคริปต์เชลล์ซึ่งเปลี่ยนเส้นทางการส่งออกที่ยังแฟ้มใน (ผ่าน>>และ2>&1.)

มีวิธีทำให้ไฟล์บันทึกนั้นหมุนหรือไม่ (ขนาดสูงสุดจากนั้นเปลี่ยนเป็นไฟล์อื่นเก็บเฉพาะไฟล์จำนวน จำกัด )

ฉันเห็นคำตอบสองสามข้อที่พูดเกี่ยวกับlogrotateโปรแกรมซึ่งฟังดูดี แต่พวกเขาก็ดูเหมือนจะเน้นไปที่โปรแกรมที่สร้างไฟล์บันทึกภายในและจัดการสัญญาณ HUP มีวิธีที่จะทำให้การทำงานนี้ด้วยสคริปต์เปลี่ยนเส้นทางออกพื้นฐานหรือไม่


1
ทำไมคุณไม่สามารถปรับเปลี่ยนสคริปต์ที่เปลี่ยนเส้นทางผลลัพธ์เพื่อให้มีตรรกะสำหรับการหมุนได้
MaQleod

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

2
คุณไม่จำเป็นต้องใช้ logrotate แต่การใช้ logrotate จะช่วยประหยัดเวลา ... โดยปกติแล้วจะมีจุดเล็ก ๆ
bubu

ตรงประเด็นของฉัน ดังนั้นมีวิธีที่จะทำให้ logrotate ทำงานกับ stdout ที่เปลี่ยนเส้นทางของกระบวนการอย่างต่อเนื่องหรือไม่?
Miral

คำตอบ:


44

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

  • Dan Bernstein's multilogจาก daemontools
  • Bruce Guenter multilogจาก daemontools-encore
  • Laurent Bercot's s6-logจาก s6
  • Gerrit Pape svlogdจาก runit
  • เวย์นมาร์แชลล์tinylogจาก perp
  • ของฉันcyclogจากnosh

เครื่องมือที่ใช้ในการประมวลผลmultilogชุดรูปแบบไฟล์บันทึกประกอบด้วย:

อ่านเพิ่มเติม


1
ขอบคุณmultilogดูเหมือนว่าสิ่งที่ฉันต้องการ
Miral

Multilog ดูเหมือนจะเป็นทางออกแบบ plug-and-play เดียวในเดเบียน (daemontools มีแพ็คเกจอย่างเป็นทางการ) แต่ในกรณีของฉันโดยเฉพาะอย่างยิ่งที่ฉันต้องการเก็บบันทึกไว้ในพาร์ติชัน fat32 การหมุนไม่ทำงานเนื่องจาก Multilog ต้องการใช้ symlink ไม่มีแบบพลักแอนด์เพลย์สำหรับฉัน :)
Arnout

ไม่สามารถเป็นจริงได้เนื่องจากmultilogไม่มีที่ไหนที่สร้างหรือต้องการลิงก์สัญลักษณ์ เป็นกลางทั้งหมดด้วยความเคารพ
JdeBP

URL ของ "อย่าใช้ logrotate หรือ newsyslog ในศตวรรษนี้" มีจุดพิเศษ
duyue

15

rotatelogsเครื่องมือมาพร้อมกับ Apache (ในbindir) (ดูเอกสาร ) ใช้เวลาการป้อนข้อมูลจาก stdin และหมุนล็อกหลังจำนวนเฉพาะในบางเวลา


14

หากคุณสามารถให้มันไปที่หนึ่งในสตรีมบันทึกมาตรฐาน (syslog, daemon, cron, ผู้ใช้, ความปลอดภัย, อีเมล ฯลฯ ) คุณสามารถใช้loggerคำสั่งและไปป์แทนได้

echo "Hello." | logger -p daemon.info

มิฉะนั้นคุณอาจจะดีกว่าการวางเนื้อหาที่บันทึกไว้ของคุณไปยังโปรแกรมหรือสคริปต์ที่กำหนดเองเพื่อจัดการกับมันหรือดูการตั้งค่าการlogrotateกำหนดค่า

แก้ไข: คำตอบของ JdeBP ดูเหมือนจะมีสิ่งที่คุณอาจมองหา


2
+1 เพื่อความง่าย BTW คุณยังสามารถกำหนดค่าสิ่งอำนวยความสะดวกที่กำหนดเอง (local0) แทนสิ่งอำนวยความสะดวกมาตรฐาน (daemon ในตัวอย่างของคุณ)
Roger Keays

14

ฉันมีปัญหาที่คล้ายกันและได้เริ่มต้นทิ้ง logrotate แต่มันกลับกลายเป็นว่า logrotate สามารถทำได้ดีจริง ๆ คำสั่งที่สำคัญคือ " copytruncate " ด้วยเหตุผลบางอย่างคำศัพท์ไม่ได้เกิดขึ้นกับ googling ใด ๆ ที่ฉันทำดังนั้นฉันจึงเพิ่มคำตอบนี้เพื่ออธิบายให้ชัดเจนถึงวิธีการใช้งานสำหรับกรณีนี้

เคล็ดลับนี้ใช้งานได้เฉพาะเมื่อการเปลี่ยนเส้นทางเสร็จสิ้นด้วย " >> " (ผนวก) แทน " > " (สร้าง)

ไฟล์กำหนดค่า (truncate.cfg):

/tmp/temp.log {
    size 10M
    copytruncate
    rotate 4
    maxage 100
}

ทดสอบโปรแกรม (ไม่เคยยอมแพ้ไฟล์) คุณสามารถดูมันเติมดิสก์และแม้ว่าการลบ logfile จะทำงาน แต่มันจะไม่เพิ่มพื้นที่ว่างบนดิสก์:

cat /dev/urandom >> /tmp/temp.log

การหมุนบันทึกการทำงาน:

logrotate truncate.cfg

มันเป็นทฤษฎีที่ดี แต่มันใช้งานไม่ได้กับทุกระบบที่ฉันได้ลองทำ ไฟล์ไม่ได้ถูกตัดทอนและโปรแกรมจะทำการต่อท้ายเหมือนเดิม (และใช่นั่นคือแม้จะมีการเปลี่ยนเส้นทางผ่าน >>.) ((BTW คำตอบนี้ได้ให้ไว้ก่อนหน้านี้แล้ว))
Miral

1
…ดังที่กล่าวไว้ในlogrotate จะไม่ตัดทอนไฟล์ต้นฉบับ (บนเว็บไซต์ Unix & Linux ของเรา) นอกจากนี้echo /dev/urandom >> /tmp/temp.logจะเขียนอักขระที่กำหนดค่าได้ 13 ตัว/tmp/temp.logจากนั้นออกทันที คุณหมายถึงcat /dev/urandomอะไร
G-Man กล่าวว่า 'Reinstate Monica'

2
เพิ่งทดสอบที่นี่และดูเหมือนว่าจะทำงาน เนื้อหาของไฟล์จะถูกคัดลอกไปยังไฟล์บันทึกใหม่ ไฟล์ต้นฉบับถูกเก็บไว้เปิดตามกระบวนการและถูกตัดทอน (ขนาดจะแสดงเป็น 0)
Philipp

1
ใช้ความระมัดระวังเกี่ยวกับการสูญเสียข้อมูลที่เป็นไปได้ด้วยการคัดลอก
wanghq

1
+1 แม้ว่า "โปรดทราบว่ามีการแบ่งเวลาเล็กน้อยระหว่างการคัดลอกไฟล์และตัดทอนดังนั้นข้อมูลการบันทึกบางอย่างอาจหายไป"
Tagar

3

ดังนั้นมีวิธีที่จะทำให้ logrotate ทำงานกับ stdout ที่เปลี่ยนเส้นทางของกระบวนการอย่างต่อเนื่องหรือไม่?

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

ข้อแม้หนึ่งข้ออาจมีหรือไม่มีปัญหาในสถานการณ์ของคุณ:

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

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


3

ใช้แบ่งมันเป็นส่วนหนึ่งของ coreutils สามารถใช้ stdin และแยกเป็นชิ้น ๆ (ขึ้นอยู่กับขนาดของชิ้นหรือจำนวนบรรทัด ฯลฯ )

ตัวอย่าง:

app | split --bytes 1G - /var/logs/put-prefix-here

Note dash (-) สั่งให้ "split" เพื่อใช้ stdin แทน file


คุณสามารถขยายคำตอบของคุณเพื่ออธิบายวิธีการดังกล่าวได้หรือไม่? ขอบคุณ
fixer1234

เพิ่งปรับปรุงคำตอบของฉันด้วยตัวอย่าง
Nazar

1G เป็นขนาดที่กำหนดเองหลังจากนั้นจะเริ่มไฟล์ใหม่?
fixer1234

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

1
@ David Richerby - วิธีเพิ่ม -u สำหรับ unbuffered หรือไม่
Nick

3

ฉันชอบmultilogกรณีการใช้งานของฉัน แต่กรณีการใช้งานของฉันช่างยุ่งยาก / เรียบง่ายจนไม่ได้จัดวางอย่างง่าย ๆ ในเอกสาร / ตัวอย่างที่ฉันพบ นี่คือตัวอย่างการหมุนหลาย multilog อย่างง่าย:

mkdir /tmp/myapp
./myapp | multilog t s10000 n5 '!tai64nlocal' /tmp/myapp 2>&1

หมายเหตุบางส่วน:

  • ดัมพ์นี้ล็อกอินเข้าสู่ไดเร็กทอรี / tmp / myapp /
  • s10000 แสดงถึง 10,000 ไบต์ *
  • n5 แสดงถึง 5 ไฟล์ * บันทึก 'ปัจจุบัน' นับเป็นหนึ่งในไฟล์ดังนั้นจึงรวมถึงบันทึกที่เก่ากว่า 4 รายการ + 'ปัจจุบัน'
  • สิ่งนี้ขึ้นอยู่กับดัดแปลงมาจากตัวอย่างที่มีให้โดยFrançois Beausoleil ที่: http://blog.teksol.info/pages/daemontools/best-practices
  • ฉันไม่เข้าใจตัวเลือกมากมาย - ฉันแนะนำคุณไปยังเอกสารต่าง ๆ เพื่อขยาย ...
  • เอกสารเตือนว่า: "Note that running processor may block any program feeding input to multilog."ที่ไหน 'โปรเซสเซอร์' เป็น'!tai64nlocal'ส่วนหนึ่งของคำสั่ง

* สำหรับหลาย ๆ แอปพลิเคชั่นนี่เป็นตัวเลือกที่แย่สำหรับการใช้งานในระยะยาว พวกเขาอนุญาตให้คุณสังเกตพฤติกรรมการบรรจุและการหมุนบันทึกได้เร็วกว่าบันทึกขนาดใหญ่

ในที่สุดอย่าลืมที่จะไม่เร่งความเร็วถ้าจำเป็น! ด้วย nohup คุณไม่จำเป็นต้อง2>&1(s = 10e6 และ n = 30 ที่นี่):

mkdir -p /tmp/myapp
nohup ./myapp | multilog t s10000000 n30 '!tai64nlocal' /tmp/myapp &

คำสั่งนั้นจะช่วยให้คุณเริ่มต้นได้


1

ฉันแค่อยากจะเพิ่มความคิดเห็นของ Sam Hendley ด้านบน:

เคล็ดลับนี้ใช้งานได้เฉพาะเมื่อการเปลี่ยนเส้นทางเสร็จสิ้นด้วย>>(ผนวก) แทน>(สร้าง)

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

เปลี่ยนเส้นทาง STDOUT และ STDERR ไปยังไฟล์บันทึกการหมุน:

  1. some-program.sh >> /tmp/output.txt 2>&1 &
  2. สร้างไฟล์กำหนดค่า logrotate ภายใต้/etc/logrotate.dสิ่งที่เรียกว่า output_roll ในกรณีของฉัน

    ตัวอย่างการกำหนดค่าสำหรับกรณีของฉัน:

    /tmp/output.txt {
        notifempty
        missingok
        size 1G
        copytruncate
        start 0
        rotate 15
        compress
    }
    
  3. ตั้งค่างาน cron ของคุณภายใน/etc/crontabไฟล์

    *  *  *  *  * root /usr/sbin/logrotate /etc/logrotate.d/output_roll
    

    นี่จะตรวจสอบไฟล์ทุกนาที คุณสามารถปรับให้เหมาะกับความต้องการของคุณ

  4. เริ่มต้นขึ้น:

    $> service crond restart
    
  5. แค่นั้นแหละ

หมายเหตุ: ฉันยังมีปัญหากับ SELinux เป็นชุดไปดังนั้นผมจึงตั้งค่าให้SELINUX=enforcingSELINUX=disabled


1

ฉันเขียนlogroteeสุดสัปดาห์นี้ ผมก็อาจจะไม่ได้ถ้าฉันได้อ่าน @ คำตอบที่ดี JdeBP multilogและ

ฉันมุ่งเน้นไปที่มันมีน้ำหนักเบาและสามารถ bzip2 ชิ้นงานที่ชอบ:

verbosecommand | logrotee \
  --compress "bzip2 {}" --compress-suffix .bz2 \
  /var/log/verbosecommand.log

อย่างไรก็ตามยังมีอีกหลายสิ่งที่ต้องทำและทดสอบ

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