systemd เมื่อ 15.04 จะไม่บันทึก stdout ของหน่วย


12

ฉันกำลังพยายามสร้าง systemd unit เป็นเว็บเซิร์ฟเวอร์ ปัจจุบันfoo.serviceไฟล์ของฉันมีลักษณะดังนี้:

[Unit]
Description=The Foo Web Server

[Service]
Type=simple
ExecStart=/opt/foo/.cabal-sandbox/bin/foo

[Install]
WantedBy=multi-user.target

fooปฏิบัติการโดยอัตโนมัติร้องขอ HTTP ทั้งหมดที่ stdout - นี่คือการทดสอบอย่างดี อย่างไรก็ตามเมื่อฉันดูบันทึกด้วยjournalctl -u fooฉันได้รับผลลัพธ์เช่นนี้เท่านั้น:

...
May 06 17:46:57 localhost systemd[1]: Stopping The Foo Web Server...
May 06 17:46:57 localhost systemd[1]: Started Foo Web Server.
May 06 17:46:57 localhost systemd[1]: Starting The Foo Web Server...
May 06 17:47:08 localhost systemd[1]: Stopping The Foo Web Server...
May 06 17:47:08 localhost systemd[1]: Started The Foo Web Server.
May 06 17:47:08 localhost systemd[1]: Starting The Foo Web Server...

มีคนอธิบายได้ไหมว่าทำไมมันไม่ได้บันทึกเอาต์พุต stdout ทั้งหมด ฉันดูคำถามก่อนหน้านี้สั้น ๆแต่ก็ไม่ได้ช่วยอะไรเลย แต่มันเป็นการพาดพิงถึงบางสิ่งบางอย่างตามแนว "... อาจไม่ทำงานสำหรับระบบที่ไม่ได้ใช้ระบบเต็ม " - นี่จะเป็นกรณีของ Ubuntu 15.04 ? ขอบคุณล่วงหน้าความช่วยเหลือใด ๆ กับสิ่งนี้จะได้รับการชื่นชมมาก!


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

1
พยายามแก้ไขสิ่งนี้ด้วย ฉันมีความประทับใจที่ systemd ทำการบัฟเฟอร์ stdout เป็น line-buffered ใน UNIX แต่ systemd ทำสิ่งของตัวเองและบัฟเฟอร์มากขึ้น (เพื่อให้เร็ว แต่อาจไร้ประโยชน์)
Velkan

ฉันมีปัญหาเดียวกันและบัฟเฟอร์ด้วยฟังก์ชั่นการพิมพ์ของงูใหญ่ก็เป็นปัญหา! ตั้งแต่ฉันใช้ Python 3 ฉันเพิ่งใช้สิ่งที่ชอบprint('Hello World!', flush=True)และนั่นก็เป็นเคล็ดลับ! เอาต์พุตเริ่มแสดงใน journalctl
timbram

คำตอบ:


9

ในความเป็นจริงการบัฟเฟอร์ใน UNIX ขึ้นอยู่กับบริบท: เมื่อ stdout ถูกเปลี่ยนเส้นทางไปยังสิ่งที่โต้ตอบเหมือนคอนโซล - โดยปกติแล้วจะเป็น line-buffered

การบัฟเฟอร์อาจมีการเปลี่ยนแปลงภายในแอปพลิเคชันโดยใช้การเรียกไลบรารีsetvbuf

แต่สามารถทำได้ด้วยคำสั่งstdbufเมื่อเรียกใช้:

ExecStart=/usr/bin/stdbuf -oL /opt/foo/.cabal-sandbox/bin/foo

(สำหรับกรณีบัฟเฟอร์บรรทัด)


สิ่งนี้ช่วยชีวิตฉันไว้! ขอบคุณมาก. แต่ฉันสับสนเล็กน้อยว่าExecStart=/my/foo/programทำไม stdout log ไม่ล้างข้อมูลเมื่อบริการถูกยกเลิก แต่จะหายไปอย่างสมบูรณ์แทน
wlnirvana

0

โดยเริ่มต้นในUbuntu 15.04 , systemdวารสารเป็นเพียงระเหยและเก็บไว้ใน/run/systemd/journalและจะหายไปในแต่ละรีบูต หากต้องการใช้เจอร์นัลsystemd แบบถาวร คุณต้องสร้างไดเร็กทอรี (และรีสตาร์ท systemd-journald.service)/var/log/journal

ดังนั้นอาจเป็นไปได้ที่stdoutผลลัพธ์จะถูกเปลี่ยนเส้นทางไปที่syslogและไม่ได้เก็บไว้ในsystemd journal สำหรับสิ่งนั้นคุณอาจต้องใช้เจอร์นัลsystemd แบบถาวร ดังอธิบายไว้ข้างต้น

คุณตรวจสอบบันทึก/var/log/syslogของคุณแล้วfooหรือยัง


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