ฉันมีล็อกไฟล์และฉันต้องการเพิ่มการประทับเวลาในแต่ละบรรทัดเมื่อเพิ่ม ดังนั้นฉันกำลังมองหาสคริปต์ที่เพิ่มการประทับเวลาในแต่ละรายการในบรรทัดบันทึกและที่สามารถทำงานเป็นงาน cron
ฉันมีล็อกไฟล์และฉันต้องการเพิ่มการประทับเวลาในแต่ละบรรทัดเมื่อเพิ่ม ดังนั้นฉันกำลังมองหาสคริปต์ที่เพิ่มการประทับเวลาในแต่ละรายการในบรรทัดบันทึกและที่สามารถทำงานเป็นงาน cron
คำตอบ:
$ cat input.log | sed -e "s/^/$(date -R) /" >> output.log
มันทำงานอย่างไร:
cat
อ่านไฟล์ที่เรียกinput.log
และพิมพ์ไปยังสตรีมเอาต์พุตมาตรฐาน
ปกติออกมาตรฐานมีการเชื่อมต่อไปยังสถานี แต่สคริปต์เล็ก ๆ น้อย ๆ นี้มี|
การเปลี่ยนเส้นทางเพื่อให้เปลือกออกมาตรฐานของการป้อนข้อมูลมาตรฐานcat
sed
sed
อ่านข้อมูล ( cat
สร้างข้อมูล) ประมวลผล (ตามสคริปต์ที่ให้มาพร้อมกับ-e
ตัวเลือก) แล้วพิมพ์ไปยังเอาต์พุตมาตรฐาน สคริปต์"s/^/$(date -R) /"
วิธีการเปลี่ยนจุดเริ่มต้นของทุกบรรทัดกับข้อความที่สร้างโดยdate -R
คำสั่ง (การก่อสร้างทั่วไปสำหรับการเปลี่ยนคำสั่ง: s/pattern/replace/
)
จากนั้นตามการ>>
bash
เปลี่ยนเส้นทางเอาต์พุตของsed
ไปยังไฟล์ที่เรียกว่าoutput.log
( >
หมายถึงแทนที่เนื้อหาไฟล์และ>>
หมายถึงการผนวกท้าย)
ปัญหาคือการ$(date -R)
ประเมินครั้งเดียวเมื่อคุณเรียกใช้สคริปต์ดังนั้นมันจะแทรกการประทับเวลาปัจจุบันไปยังจุดเริ่มต้นของแต่ละบรรทัด การประทับเวลาปัจจุบันอาจห่างจากช่วงเวลาหนึ่งเมื่อมีการสร้างข้อความ เพื่อหลีกเลี่ยงมันคุณต้องประมวลผลข้อความตามที่เขียนไปยังไฟล์ไม่ใช่งาน cron
เปลี่ยนเส้นทางกระแสมาตรฐานอธิบายไว้ข้างต้นเรียกว่าท่อ คุณสามารถเปลี่ยนเส้นทางไม่ใช่เพียงแค่|
ระหว่างคำสั่งในสคริปต์ แต่ผ่านไฟล์ FIFO ( ชื่อไปป์ที่มีชื่อ ) โปรแกรมหนึ่งจะเขียนไปยังไฟล์และอีกโปรแกรมจะอ่านข้อมูลและรับมันเมื่อส่งครั้งแรก
เลือกตัวอย่าง:
$ mkfifo foo.log.fifo
$ while true; do cat foo.log.fifo | sed -e "s/^/$(date -R) /" >> foo.log; done;
# have to open a second terminal at this point
$ echo "foo" > foo.log.fifo
$ echo "bar" > foo.log.fifo
$ echo "baz" > foo.log.fifo
$ cat foo.log
Tue, 20 Nov 2012 15:32:56 +0400 foo
Tue, 20 Nov 2012 15:33:27 +0400 bar
Tue, 20 Nov 2012 15:33:30 +0400 baz
มันทำงานอย่างไร:
mkfifo
สร้างไปป์ที่มีชื่อ
while true; do sed ... ; done
ทำงานวนรอบไม่สิ้นสุดและทุกครั้งที่มันทำงานsed
ด้วยการเปลี่ยนเส้นทางfoo.log.fifo
ไปยังอินพุตมาตรฐานของมัน sed
บล็อกในการรอคอยสำหรับการป้อนข้อมูลfoo.log
และจากนั้นประมวลผลข้อความที่ได้รับและพิมพ์มันออกมาตรฐานเปลี่ยนเส้นทางไปยัง
ณ จุดนี้คุณต้องเปิดหน้าต่างเทอร์มินัลใหม่เนื่องจากการวนซ้ำใช้เทอร์มินัลปัจจุบัน
echo ... > foo.log.fifo
พิมพ์ข้อความไปยังเอาต์พุตมาตรฐานเปลี่ยนเส้นทางไปยังไฟล์ fifo และsed
รับและประมวลผลและเขียนไปยังไฟล์ปกติ
หมายเหตุสำคัญคือฟีฟ่าเช่นเดียวกับท่ออื่น ๆ ที่ไม่มีความรู้สึกหากด้านใดด้านหนึ่งไม่ได้เชื่อมต่อกับกระบวนการ หากคุณพยายามเขียนไปที่ไพพ์กระบวนการปัจจุบันจะบล็อกจนกว่าจะมีคนอ่านข้อมูลทางด้านอื่นของไพพ์ หากคุณต้องการอ่านจากไปป์กระบวนการจะบล็อกจนกว่าจะมีคนเขียนข้อมูลไปยังไปป์ sed
ห่วงในตัวอย่างข้างต้นไม่ทำอะไรเลย (นอน) echo
จนกว่าคุณจะทำ
สำหรับสถานการณ์เฉพาะของคุณคุณเพียงกำหนดค่าแอปพลิเคชันของคุณให้เขียนข้อความบันทึกลงในไฟล์ Fifo หากคุณไม่สามารถกำหนดค่าได้เพียงลบไฟล์บันทึกดั้งเดิมแล้วสร้างไฟล์ Fifo แต่โปรดทราบอีกครั้งว่าถ้าsed
ลูปจะตายด้วยเหตุผลบางอย่าง - โปรแกรมของคุณจะถูกบล็อกเมื่อพยายามไปwrite
ยังไฟล์จนกว่าจะมีคนread
มาจากฟีฟ่า
ประโยชน์คือการประทับเวลาปัจจุบันที่ประเมินและแนบกับข้อความขณะที่โปรแกรมเขียนลงไฟล์
tailf
tailf
ที่จะทำให้การเขียนเพื่อบันทึกและประมวลผลเป็นอิสระมากขึ้นคุณสามารถใช้สองไฟล์ปกติด้วย แอปพลิเคชันจะเขียนข้อความไปยังไฟล์ raw และกระบวนการอื่นอ่านบรรทัดใหม่ (ตามเพื่อเขียนแบบอะซิงโครนัส) และประมวลผลข้อมูลด้วยการเขียนไปยังไฟล์ที่สอง
ลองมาตัวอย่าง:
# will occupy current shell
$ tailf -n0 bar.raw.log | while read line; do echo "$(date -R) $line" >> bar.log; done;
$ echo "foo" >> bar.raw.log
$ echo "bar" >> bar.raw.log
$ echo "baz" >> bar.raw.log
$ cat bar.log
Wed, 21 Nov 2012 16:15:33 +0400 foo
Wed, 21 Nov 2012 16:15:36 +0400 bar
Wed, 21 Nov 2012 16:15:39 +0400 baz
มันทำงานอย่างไร:
เรียกใช้tailf
กระบวนการที่จะติดตามเขียนbar.raw.log
และพิมพ์ไปยังเอาต์พุตมาตรฐานที่เปลี่ยนเส้นทางไปยังwhile read ... echo
ลูปไม่สิ้นสุด วงนี้จะดำเนินการสองการกระทำ: อ่านข้อมูลจากอินพุตมาตรฐานให้กับตัวแปรบัฟเฟอร์ที่เรียกว่าและเวลาแล้วที่สร้างเขียนด้วยข้อมูลที่บัฟเฟอร์ต่อไปนี้line
bar.log
bar.raw.log
เขียนข้อความบางอย่างเพื่อ คุณต้องทำสิ่งนี้ในหน้าต่างเทอร์มินัลแยกต่างหากเพราะอันแรกจะถูกครอบครองโดยtailf
ที่จะติดตามการเขียนและทำงานของมัน ค่อนข้างง่าย
tailf
ข้อดีคือใบสมัครของคุณจะไม่ปิดกั้นถ้าคุณฆ่า ข้อเสียคือการประทับเวลาที่แม่นยำน้อยลงและการทำซ้ำไฟล์บันทึก
tailf
เพิ่มวิธีการใช้งานที่ถูกต้อง อันที่จริงวิธีtailf
ดูเหมือนจะสง่างามกว่า แต่ฉันปล่อยให้ฟีฟ่าด้วยความหวังว่ามันจะมีประโยชน์สำหรับใครบางคน
คุณสามารถใช้ts
สคริปต์ perl จากmoreutils
:
$ echo test | ts %F-%H:%M:%.S
2012-11-20-13:34:10.731562 test
แก้ไขจากคำตอบของ Dmitry Vasilyanov
ใน bash script คุณสามารถเปลี่ยนเส้นทางและล้อมรอบเอาต์พุตด้วยการประทับเวลาทีละบรรทัดได้ทันที
ควรใช้เมื่อใด:
tailf
สำหรับล็อกไฟล์ตามที่ Dmitry Vasilyanov กล่าวตัวอย่างชื่อfoo.sh
:
#!/bin/bash
exec &> >(while read line; do echo "$(date +'%h %d %H:%M:%S') $line" >> foo.log; done;)
echo "foo"
sleep 1
echo "bar" >&2
sleep 1
echo "foobar"
และผลลัพธ์:
$ bash foo.sh
$ cat foo.log
May 12 20:04:11 foo
May 12 20:04:12 bar
May 12 20:04:13 foobar
มันทำงานอย่างไร
exec &>
เปลี่ยนเส้นทาง stdout และ stderr ไปยังสถานที่เดียวกัน>( ... )
ไพพ์เอาต์พุตไปยังคำสั่งด้านในแบบอะซิงโครนัสตัวอย่างเช่น:
pipe timestamp และบันทึกลงไฟล์
#!/bin/bash
exec &> >(while read line; do echo "$(date +'%h %d %H:%M:%S') $line" >> foo.log; done;)
echo "some script commands"
/path-to/some-thrid-party-programs
หรือพิมพ์เวลาประทับและเข้าสู่ระบบเพื่อ stdout
#!/bin/bash
exec &> >(while read line; do echo "$(date +'%h %d %H:%M:%S') $line"; done;)
echo "some script commands"
/path-to/some-thrid-party-programs
จากนั้นบันทึกไว้ใน/etc/crontab
การตั้งค่า
* * * * * root /path-to-script/foo.sh >> /path-to-log-file/foo.log
ฉันใช้ts
วิธีนี้เพื่อรับรายการที่มีการประทับเวลาในบันทึกข้อผิดพลาดสำหรับสคริปต์ที่ฉันใช้เพื่อรับ Cacti ที่เต็มไปด้วยสถิติของโฮสต์ระยะไกล
เพื่อทดสอบ Cacti ฉันใช้rand
เพื่อเพิ่มค่าสุ่มบางอย่างที่ฉันใช้สำหรับกราฟอุณหภูมิเพื่อตรวจสอบอุณหภูมิระบบของฉัน
Pushmonstats.sh เป็นสคริปต์ที่รวบรวมสถิติอุณหภูมิระบบของพีซีของฉันและส่งไปยัง Raspberry Pi ที่ Cacti ทำงาน เมื่อไม่นานมานี้เครือข่ายติดขัด ฉันมีเวลา SSH เท่านั้นในบันทึกข้อผิดพลาดของฉัน น่าเสียดายที่ไม่มีรายการเวลาในบันทึกนั้น ฉันไม่รู้วิธีเพิ่มการประทับเวลาลงในรายการบันทึก ดังนั้นหลังจากการค้นหาบางบนอินเทอร์เน็ตฉัน stumbled ts
เมื่อโพสต์นี้และนี่คือสิ่งที่ผมทำโดยใช้
rand
เพื่อทดสอบผมใช้เป็นตัวเลือกที่ไม่รู้จักกับ ซึ่งให้ข้อผิดพลาดกับ stderr ในการจับภาพฉันเปลี่ยนเส้นทางไปยังไฟล์ชั่วคราว จากนั้นฉันใช้ cat เพื่อแสดงเนื้อหาของไฟล์และไพพ์ไปยังts
เพิ่มรูปแบบเวลาที่ฉันพบในโพสต์นี้และในที่สุดก็เข้าสู่ไฟล์ข้อผิดพลาด จากนั้นฉันจะล้างเนื้อหาของไฟล์ชั่วคราวมิฉะนั้นฉันจะได้รับสองรายการสำหรับข้อผิดพลาดเดียวกัน
crontab:
* * * * * /home/monusr/bin/pushmonstats.sh 1>> /home/monusr/pushmonstats.log 2> /home/monusr/.err;/bin/cat /home/monusr/.err|/usr/bin/ts %F-%H:%M:%.S 1>> /home/monusr/pushmonstats.err;> /home/monusr/.err
สิ่งนี้ให้สิ่งต่อไปนี้ในบันทึกข้อผิดพลาดของฉัน:
2014-03-22-19:17:53.823720 rand: unknown option -- '-l'
บางทีนี่อาจไม่ใช่วิธีที่ยอดเยี่ยมที่จะทำ แต่ใช้งานได้ ฉันสงสัยว่ามีวิธีที่สง่างามกว่านี้หรือไม่