มีวิธีในการทำ journalctl แสดงบันทึกจาก“ ครั้งล่าสุดที่ foo.service วิ่งไป” หรือไม่?


16

ฉันสนใจสิ่งนี้เป็นพิเศษโดยดูที่ผลลัพธ์ของบริการถ่ายภาพที่ทำงานบนตัวจับเวลา --unitธงอยู่ใกล้ แต่มันเชื่อมวิ่งทั้งหมดของการให้บริการร่วมกัน วิธีที่ชัดเจนที่สุดที่ฉันนึกได้ก็คือการกรอง PID แต่นั่นทำให้ฉันกังวลเกี่ยวกับการใช้ PID ซ้ำ / บริการที่แยกและการรับ PID ล่าสุดนั้นไม่สะดวก มีตัวระบุอื่น ๆ ที่สอดคล้องกับการเรียกใช้บริการครั้งเดียวซึ่งฉันสามารถใช้เพื่อกรองบันทึกได้หรือไม่

แก้ไข: ฉันจะยินดียอมรับเผด็จการ "ไม่" ถ้านั่นคือคำตอบที่แท้จริง

คำตอบ:


8

ตั้งแต่systemdเวอร์ชั่น232เรามีคอนเซปต์ของการเรียก ID ทุกครั้งที่มีการเรียกใช้หน่วยจะมีรหัสการเรียกใช้ 128 บิตที่ไม่ซ้ำกัน ซึ่งแตกต่างจากMainPIDที่สามารถนำกลับมาใช้ใหม่หรือActiveEnterTimestampที่มีปัญหาการแก้ไขมันเป็นวิธีที่ไม่ปลอดภัยที่จะได้รับบันทึกทั้งหมดของการร้องขอหน่วย systemd โดยเฉพาะ

เพื่อรับ ID การร้องขอล่าสุดของหน่วย

$ systemctl show --value -p InvocationID openipmi
bd3eb84c3aa74169a3dcad2af183885b

ในการรับวารสารของคำภาวนาล่าสุดของพูดopenipmiไม่ว่าจะล้มเหลวหรือไม่คุณสามารถใช้หนึ่งซับ

$ journalctl _SYSTEMD_INVOCATION_ID=`systemctl show -p InvocationID --value openipmi.service`
-- Logs begin at Thu 2018-07-26 12:09:57 IDT, end at Mon 2019-07-08 01:32:50 IDT. --
Jun 21 13:03:13 build03.lbits openipmi[1552]:  * Starting ipmi drivers
Jun 21 13:03:13 build03.lbits openipmi[1552]:    ...fail!
Jun 21 13:03:13 build03.lbits openipmi[1552]:    ...done.

(โปรดทราบว่า--valueมีให้บริการตั้งแต่systemd 230เก่ากว่าInvocationID)


1
หากมีคนพยายามตรวจสอบสิ่งนี้: journalctl --user -u UNITFILE -f -o json-prettyอาจเป็นประโยชน์ คุณกำลังมองหาMESSAGEช่องโดยเฉพาะ ฉันพบว่าคุณอาจต้องใช้USER_INVOCATION_IDและบางข้อความไม่มีรหัสการร้องขอใด ๆ ติดอยู่ดังนั้นจึงไม่สามารถกรองผ่านกลไกนี้ ไม่แน่ใจว่าทำไมการบันทึกของฉันอาจผิดพลาด ..
karlicoss

14

ฉันไม่แน่ใจว่าการประทับเวลาใดที่เหมาะสมที่สุด แต่สิ่งนี้ใช้ได้สำหรับฉัน หวังว่าจะมีวิธีที่ดีกว่าในการทำงานกับการประทับเวลาจากsystemctl showกว่า awk - ไม่สามารถหาวิธีควบคุมรูปแบบการประทับเวลาได้

unit=foo.service

ts=$(systemctl show -p ActiveEnterTimestamp $unit)

echo $ts
ActiveEnterTimestamp=Fri 2016-11-11 12:30:01 MST

journalctl -u $unit --since "$(echo $ts | awk '{print $2 $3}')"

ในกรณีที่มีใครบางคนต้องการมันเป็นซับเดียว: journalctl --since " systemctl show -p ActiveEnterTimestamp thermo.service | awk '{print $2 \" \" $3}'" -fu thermo.service | น้อยลง
DimanNe

คุณสามารถใช้งานsystemctl show -p ActiveEnterTimestamp --value $unitได้ดังนั้นจึงไม่จำเป็นต้องเพิ่ม awk
karlicoss

4

คุณสามารถใช้การตั้งค่าสถานะการเริ่มระบบเพื่อดึงข้อมูลล็อกจากการเริ่มระบบเท่านั้น เช่น

journalctl _SYSTEMD_UNIT=avahi-daemon.service -b 5

2
สิ่งนี้คล้ายกับสิ่งที่ฉันต้องการ แต่มันไม่ทำงานในสถานการณ์เช่น: 1) หากเครื่องถูกรีบูทตั้งแต่ครั้งล่าสุดที่บริการรันหรือ 2) ถ้าบริการได้เริ่มทำงานหลายครั้งตั้งแต่การบู๊ตครั้งสุดท้าย
Jack O'Connor

ฉันไม่แน่ใจว่าทำไมมันไม่ทำงานสำหรับกรณีที่ 1 หากมีการรีบูทเครื่องก็จะทำการรีบูทด้วย คุณเพียงแค่ต้องไปที่การบูตที่เฉพาะเจาะจงและดึงข้อมูลของคุณ เกี่ยวกับเรื่องที่สอง ... คุณพูดถูก บันทึกเสียงขึ้นอยู่กับจำนวนครั้งที่มีการรีบูทบริการ แต่เมื่อคุณเห็น pid บริการของคุณแล้วคุณสามารถกรองโดยใช้อาร์กิวเมนต์ _PID = XXX โอกาสในการใช้ pid เดิมซ้ำสำหรับบริการเดียวกันในวงจรการบูตเดียวกันคือ…ไม่คิดเลย… แต่ใกล้เคียงกับเป็นไปไม่ได้
Nikolaidis Fotis

ฉันสนใจที่จะจัดการกับบริการที่ไม่จำเป็นต้องทำงานในการบู๊ตเพราะพวกมันอยู่ในเครื่องจับเวลาหรือเพราะมันเป็นคำสั่งแบบครั้งเดียว
Jack O'Connor

4

สิ่งเหล่านี้อาจช่วยคุณได้:

  • journalctl -u foo.service | tail -n 2

    หรือแทนที่2ด้วยจำนวนบรรทัดที่คาดหวัง

  • journalctl -u foo.service --since = ' 2016-04-11 13:00:00 '

คุณสามารถรวมมันเข้าด้วยกันเพื่อให้ได้เวลาประทับเวลาล่าสุดครั้งแรกจากนั้นใช้การประทับเวลานั้นกับสวิตช์ --since


วิธีนี้ให้ความรู้สึกคล้ายกับวิธีการแก้ปัญหาคล้ายกับวิธี PID หากบริการของฉันทำงานนานหลายวินาทีและแยกสายบันทึกออกเป็นจำนวนมากฉันต้องไปค้นหาบรรทัดแรกที่มีการประทับเวลาเริ่มต้นที่ฉันสนใจ มันไม่ได้ผลดีนักในสคริปต์
Jack O'Connor

3

คุณสามารถใช้ฟิลเตอร์ฟิลด์กับ Journalctl เช่น

journalctl _PID=1234

รับรายการเขตข้อมูลทั้งหมดที่มีโดยใช้:

journalctl --fields --unit kubelet

_PIDหนึ่งในสนามที่มีอยู่

คุณสามารถขอรับ PID ของกระบวนการที่กำลังใช้อยู่pidofหรือsystemctl show --property MainPID <SERVICE_NAME>

ดังนั้นนี่คือวิธีที่ฉันได้รับบันทึกจากกระบวนการ Kubernetes kubelet ปัจจุบัน:

# journalctl --unit kubelet _PID=$(systemctl show --property MainPID kubelet 2>/dev/null | cut -d= -f2) | head

บอกฉันทีว่าทำไมฉันถึง Kubernetes ติดตั้งยากมาก :-(


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