ทำความเข้าใจเกี่ยวกับการเข้าสู่ระบบใน Linux


62

ตามที่ฉันเข้าใจลีนุกซ์เคอร์เนลจะบันทึก/proc/kmsgไฟล์ (ส่วนใหญ่เป็นข้อความเกี่ยวกับฮาร์ดแวร์) และ/dev/logซ็อกเก็ต? มีที่ไหนอีกไหม แอปพลิเคชันอื่นสามารถส่งข้อความถึง/proc/kmsgหรือ/dev/logไม่ สุดท้าย แต่ไม่ท้ายสุดฉันถูกต้องหรือไม่ว่ามันคือ syslog daemon ( rsyslog , syslog-ng ) ที่ตรวจสอบข้อความจากสองที่จากนั้นกระจายไปยังไฟล์ต่าง ๆ เช่น/var/log/messagesหรือ/var/log/kern.logเซิร์ฟเวอร์กลาง syslog

คำตอบ:


81

อย่างง่ายมันจะมากหรือน้อยเช่นนี้

เคอร์เนลบันทึกข้อความ (ใช้printk()ฟังก์ชั่น) ไปยังบัฟเฟอร์วงแหวนในพื้นที่เคอร์เนล ข้อความเหล่านี้มีให้สำหรับแอปพลิเคชันพื้นที่ผู้ใช้ในสองวิธี: ผ่าน/proc/kmsgไฟล์ (โดย/procมีการติดตั้ง) และผ่านsys_syslogsyscall

: มีสองโปรแกรมหลักที่อ่าน (และบางส่วนสามารถควบคุม) บัฟเฟอร์แหวนเคอร์เนลที่อยู่และdmesg(1) klogd(8)อดีตมีวัตถุประสงค์เพื่อให้ทำงานตามความต้องการโดยผู้ใช้ในการพิมพ์เนื้อหาของบัฟเฟอร์แหวน หลังคือ daemon ที่อ่านข้อความจาก/proc/kmsg(หรือการโทรsys_syslogหาก/procไม่ถูกเมาท์) และส่งไปยังsyslogd(8)หรือไปยังคอนโซล ที่ครอบคลุมด้านเคอร์เนล

syslogd(8)ในพื้นที่ของผู้ใช้มี นี่เป็น daemon ที่ฟังซ็อกเก็ตโดเมน UNIX จำนวนมาก (ส่วนใหญ่/dev/logแต่สามารถกำหนดค่าอื่น ๆ ได้) และเลือกที่จะพอร์ต UDP 514 สำหรับข้อความ นอกจากนี้ยังได้รับข้อความจากklogd(8)( syslogd(8)ไม่สนใจ/proc/kmsg) จากนั้นก็เขียนข้อความเหล่านี้บางไฟล์ใน/logหรือชื่อ pipes หรือส่งไปยังโฮสต์ระยะไกลบาง (ผ่านsyslogโปรโตคอล UDP พอร์ต 514) /etc/syslog.confเช่นการกำหนดค่าใน

โดยทั่วไปแอปพลิเคชันพื้นที่ผู้ใช้จะใช้libcฟังก์ชันsyslog(3)เพื่อบันทึกข้อความ libcส่งข้อความเหล่านี้ไปยังซ็อกเก็ตโดเมน UNIX /dev/log(ที่พวกเขาจะอ่านได้โดยsyslogd(8)) แต่ถ้าโปรแกรมchroot(2)-ed ข้อความอาจจะจบลงด้วยการถูกเขียนไปยังซ็อกเก็ตอื่น ๆ Fi /var/named/dev/logเพื่อ แน่นอนว่าเป็นสิ่งจำเป็นสำหรับแอปพลิเคชันที่ส่งบันทึกเหล่านี้และsyslogd(8)ยอมรับตำแหน่งของซ็อกเก็ตเหล่านี้ ด้วยเหตุผลเหล่านี้สามารถกำหนดค่าให้ฟังซ็อกเก็ตเพิ่มเติมนอกเหนือจากมาตรฐานsyslogd(8)/dev/log

ในที่สุดsyslogโปรโตคอลเป็นเพียงโปรโตคอลดาต้าแกรม ไม่มีสิ่งใดที่ทำให้แอปพลิเคชันหยุดการส่งดาตาแกรม syslog ไปยังซ็อกเก็ตโดเมน UNIX ใด ๆ (หากว่าข้อมูลประจำตัวของมันอนุญาตให้เปิดซ็อกเก็ตได้) โดยไม่ผ่านsyslog(3)ฟังก์ชันในlibcทั้งหมด หากดาต้าแกรมที่มีรูปแบบถูกต้องสามารถใช้พวกเขาเป็นถ้าข้อความถูกส่งผ่านsyslogd(8)syslog(3)

แน่นอนข้างต้นครอบคลุมเฉพาะทฤษฎีการบันทึก "แบบคลาสสิค" daemons อื่น ๆ (เช่นrsyslogและsyslog-ngตามที่คุณพูดถึง) สามารถแทนที่แบบธรรมดาsyslogd(8)และทำสิ่งต่าง ๆ ได้ดีเช่นส่งข้อความไปยังโฮสต์ระยะไกลผ่านการเชื่อมต่อ TCP ที่เข้ารหัสไว้ให้การประทับเวลาความละเอียดสูงและอื่น ๆ และนั่นก็systemdคือ phagocytosis ที่ค่อยๆช้าลงในส่วนของ UNIX ของ Linux systemdมีกลไกการบันทึกของตัวเอง แต่คนอื่นจะต้องบอกเล่าเรื่องราว :)

ความแตกต่างกับโลก * BSD:

ใน * BSD ไม่มีklogd(8)และ/procไม่มีอยู่ (บน OpenBSD) หรือล้าสมัย (FreeBSD และ NetBSD) เป็นส่วนใหญ่ syslogd(8)อ่านข้อความเคอร์เนลจากอุปกรณ์ตัวละคร/dev/klogและdmesg(1)ใช้/dev/kmemในการถอดรหัสชื่อเคอร์เนล เพียง OpenBSD /dev/logมี FreeBSD ใช้สองซ็อกเก็ตโดเมน UNIX /var/run/logและvar/rub/logprivแทนและ NetBSD /var/run/logมี


3
nit: rsyslog ได้รับความนิยมมากขึ้นในขณะนี้ (เริ่มต้นสำหรับ Fedora, Debian) และมันไม่ได้ใช้ klogd แยกต่างหาก ดูเหมือนว่า syslog-ng ไม่ได้ (ตามความชอบ)
sourcejedi

@sourcejedi ฉันไม่ได้ติดตามลีนุกซ์ทั้งหมดอย่างใกล้ชิดในเวลาไม่กี่ปีที่ผ่านมา แต่ IIRC rsyslogไม่ได้ใช้klogd(8)เพราะรากมันกลับไปไม่ใช่เพราะเพิ่งตัดสินใจอย่างชัดเจนที่จะทำมัน หน่วยความจำของฉันสามารถล้มเหลวได้ อย่างไรก็ตามอย่างที่ฉันบอกว่าฉันแค่พยายามที่จะครอบคลุมการบันทึก "คลาสสิก"
lcd047

1
@ lcd047, @sourcejedi ขอบคุณสำหรับการตอบกลับ! ฉันมีหนึ่งระบบ Debian 7 กับการrsyslogdทำงานและหนึ่ง Ubuntu 12.04 กับการsyslog-ngทำงานและพวกเขาทั้งสองมีไฟล์ที่/proc/kmsgเปิดตามที่lsofกล่าวklogdคือไม่ได้ใช้ สิ่งที่น่าสนใจอีกอย่างหนึ่งที่ฉันสังเกตเห็นคือข้อความบันทึกจะถูกเก็บไว้ใน/proc/kmsgไฟล์หากไม่มี syslog daemon กำลังทำงานและสามารถดูสิ่งเหล่านั้นด้วยตัวอย่างcatหรือโปรแกรมแก้ไขข้อความ อย่างไรก็ตามเป็นไปได้เพียงเพื่อดูข้อความเหล่านั้นเพียงครั้งเดียวเพราะพวกเขาหายไปหลังจากดู สุดท้าย แต่ไม่dmesgท้ายสุดการดำเนินการไม่ได้ลบเนื้อหาของ/proc/kmsgไฟล์
มาร์ติน

1
@Martin /proc/kmsgไม่ใช่ไฟล์ปกติไม่มีสิ่งใด "เก็บไว้" ที่นั่น แต่เป็นเพียงมุมมองของบัฟเฟอร์ของเคอร์เนล คุณสามารถอ่านได้catอย่างแม่นยำเพราะคุณไม่ได้klogd(8)ทำงาน (คุณควรรันklogd(8)หรือcat /proc/kmsgบล็อก) dmesg(1)อ่านข้อความจาก/dev/kmsgมากกว่า/proc/kmsg; และยังสามารถล้างบัฟเฟอร์ถ้าคุณบอกให้
lcd047

1
systemd has its own logging mechanisms, but that story would have to be told by somebody else. :)- คุณบอกได้ไหมว่าคุณมีความสามารถ :-)
ฟลาเวียส

51

คำตอบอื่น ๆ อธิบายตามที่ผู้เขียนกล่าวว่า "การบันทึกแบบคลาสสิค" ใน Linux นั่นไม่ใช่ว่าสิ่งต่าง ๆ จะทำงานในระบบจำนวนมากในทุกวันนี้

เคอร์เนล

กลไกเคอร์เนลเปลี่ยนไป

เคอร์เนลสร้างเอาต์พุตไปยังบัฟเฟอร์ในหน่วยความจำ แอปพลิเคชันซอฟต์แวร์สามารถเข้าถึงได้สองวิธี ระบบย่อยเข้าสู่ระบบมักจะเข้าถึงมันเป็นหลอก FIFO /proc/kmsgชื่อ แหล่งข้อมูลบันทึกนี้ไม่สามารถใช้ร่วมกันระหว่างเครื่องอ่านบันทึกได้เนื่องจากเป็นแบบอ่านครั้งเดียว หากกระบวนการจำนวนมากใช้ร่วมกันกระบวนการเหล่านั้นจะได้รับเพียงส่วนหนึ่งของสตรีมข้อมูลบันทึกเคอร์เนล มันเป็นแบบอ่านอย่างเดียว

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

/proc/kmsgและ/dev/kmsgจัดเตรียมข้อมูลบันทึกในรูปแบบที่ไม่ใช่ RFC-5424

การประยุกต์ใช้งาน

แอปพลิเคชันมีการเปลี่ยนแปลง

syslog()ฟังก์ชั่นของไลบรารี GNU C ในความพยายามหลักในการเชื่อมต่อกับAF_LOCALซ็อกเก็ตดาตาแกรมที่มีชื่อ/dev/logและเขียนรายการบันทึกไว้ ( syslog()ฟังก์ชั่นไลบรารี BSD C ปัจจุบันใช้/var/run/logเป็นชื่อซ็อกเก็ตและลอง/var/run/logprivก่อน) แอปพลิเคชันสามารถมีรหัสของตัวเองเพื่อทำสิ่งนี้โดยตรง ฟังก์ชั่นห้องสมุดเป็นเพียงรหัส (เพื่อเปิดเชื่อมต่อเขียนและปิดซ็อกเก็ต) ดำเนินการในบริบทกระบวนการของแอปพลิเคชันหลังจากทั้งหมด

แอปพลิเคชันยังสามารถส่งข้อความ RFC 5424 ผ่านทาง UDP ไปยังเซิร์ฟเวอร์ RFC 5426 ในพื้นที่หากมีใครกำลังฟังบนซ็อกเก็ตAF_INET/ AF_INET6เดตาแกรมบนเครื่อง

ต้องขอบคุณแรงกดดันจากโลก daemontools ในช่วงสองทศวรรษที่ผ่านมาdæmonsจำนวนมากรองรับการทำงานในโหมดที่พวกเขาไม่ได้ใช้syslog()ฟังก์ชั่นไลบรารีGNU C หรือซ็อกเก็ต UDP แต่เพียงคายบันทึกข้อมูลออกไปยังข้อผิดพลาดมาตรฐานใน แฟชั่นยูนิกซ์สามัญ

การจัดการบันทึกด้วย nosh และครอบครัว daemontools โดยทั่วไป

ด้วยชุดเครื่องมือ daemontools ตระกูลมีความยืดหยุ่นในการบันทึก แต่โดยทั่วไปทั่วทั้งครอบครัวความคิดคือdæmon "main" แต่ละอันมีdæmonที่เกี่ยวข้องกับ "การบันทึก" "main" dæmonsทำงานเหมือนกับกระบวนการที่ไม่ใช่dæmonและเขียนข้อความบันทึกลงในข้อผิดพลาดมาตรฐาน (หรือเอาต์พุตมาตรฐาน) ซึ่งระบบย่อยการจัดการบริการจัดให้มีการเชื่อมต่อผ่านไพพ์ (ซึ่งเปิดค้างไว้เพื่อให้ข้อมูลบันทึกไม่สูญหาย บริการเริ่มต้นใหม่) ไปที่อินพุตมาตรฐานของ "การบันทึก" dæmon

ทั้งหมดของ "เข้าสู่ระบบ" dæmonsเรียกใช้โปรแกรมที่ล็อกอยู่ที่ไหนสักแห่ง โดยทั่วไปโปรแกรมนี้คล้ายmultilogหรือcyclogอ่านจากอินพุตมาตรฐานและไฟล์บันทึกการเขียน (nanosecond timestamped) ในไดเร็กตอรี่ที่มีการ จำกัด ขนาด, หมุนโดยอัตโนมัติ, เอกสิทธิ์เฉพาะการเขียน, โดยทั่วไปแล้วสิ่งเหล่านี้ทั้งหมดทำงานภายใต้การอุปถัมภ์ของบัญชีผู้ใช้ที่ไม่มีสิทธิพิเศษแต่ละบัญชี

ดังนั้นหนึ่งจบลงด้วยระบบการบันทึกการกระจายส่วนใหญ่ที่มีข้อมูลบันทึกการให้บริการของแต่ละการประมวลผลแยกต่างหาก

หนึ่งสามารถเรียกใช้สิ่งที่ต้องการklogdหรือsyslogdหรือrsyslogdภายใต้การจัดการบริการ daemontools ครอบครัว แต่โลก daemontools ตระหนักเมื่อหลายปีก่อนว่าโครงสร้างการจัดการบริการด้วย "การบันทึก" dæmonsยืมตัวเองค่อนข้างเรียบร้อยเพื่อทำสิ่งต่าง ๆ ในแบบที่เรียบง่าย ไม่จำเป็นต้องทำให้แฟนสตรีมของบันทึกทั้งหมดเป็นหนึ่งใน mish-mash ที่แยกวิเคราะห์ข้อมูลบันทึกจากนั้นให้แฟนสตรีมกลับไปที่ไฟล์บันทึกแยกต่างหาก จากนั้น (ในบางกรณี) ใส่กลไกการหมุนบันทึกภายนอกที่ไม่น่าเชื่อถือที่ด้านข้าง โครงสร้าง daemontools-family เป็นส่วนหนึ่งของการจัดการบันทึกมาตรฐานของมันทำการหมุนบันทึกการเขียน logfile และการแยกกระแส

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

ชุดเครื่องมือ nosh เป็นตัวอย่างนี้ ในขณะที่หนึ่งสามารถทำงานrsyslogdภายใต้มันออกมาจากกล่องและเพียงแค่จัดการเคอร์เนล/run/logและ UDP เข้าสู่ระบบในทางเก่า; มันยังให้มากขึ้น "daemontools พื้นเมือง" วิธีการในการเข้าสู่ระบบสิ่งเหล่านี้:

  • klogdบริการที่อ่านจาก/proc/kmsgและก็เขียนว่ากระแสบันทึกข้อผิดพลาดมาตรฐานของมัน klog-readนี้จะกระทำโดยโปรแกรมที่ง่ายชื่อ การบันทึกที่เกี่ยวข้องจะฟีดสตรีมการบันทึกบนอินพุตมาตรฐานลงใน/var/log/sv/klogdไดเรกทอรีบันทึก
  • local-syslog-readบริการที่อ่านจากดาต้าแกรม/dev/log( /run/logบน BSDs) และก็เขียนว่ากระแสบันทึกข้อผิดพลาดมาตรฐานของมัน syslog-readนี้จะกระทำโดยโปรแกรมชื่อ การบันทึกที่เกี่ยวข้องจะฟีดสตรีมการบันทึกบนอินพุตมาตรฐานลงใน/var/log/sv/local-syslog-readไดเรกทอรีบันทึก
  • udp-syslog-readบริการที่ฟังบนพอร์ต UDP syslog อ่านสิ่งที่มันจะถูกส่งไปมันและก็เขียนว่ากระแสบันทึกข้อผิดพลาดมาตรฐานของมัน syslog-readอีกครั้งโปรแกรมคือ การบันทึกที่เกี่ยวข้องจะฟีดสตรีมการบันทึกบนอินพุตมาตรฐานลงใน/var/log/sv/udp-syslog-readไดเรกทอรีบันทึก
  • (บน BSDs) local-priv-syslog-readบริการที่อ่านดาตาแกรมจาก/run/logprivและเขียนสตรีมบันทึกนั้นไปยังข้อผิดพลาดมาตรฐาน syslog-readอีกครั้งโปรแกรมคือ การบันทึกที่เกี่ยวข้องจะฟีดสตรีมการบันทึกบนอินพุตมาตรฐานลงใน/var/log/sv/local-priv-syslog-readไดเรกทอรีบันทึก

ชุดเครื่องมือยังมาพร้อมกับexport-to-rsyslogเครื่องมือที่สามารถตรวจสอบหนึ่งหรือหลายไดเรกทอรีบันทึก (ใช้ระบบเคอร์เซอร์บันทึกไม่ล่วงล้ำ) และส่งรายการใหม่ในรูปแบบ RFC 5424 ผ่านเครือข่ายไปยังเซิร์ฟเวอร์ RFC 5426 ที่กำหนด

การจัดการบันทึกด้วย systemd

systemd systemd-journaldมีโปรแกรมการจัดการบันทึกเดียวเสาหิน สิ่งนี้ทำงานเป็นบริการที่จัดการโดย systemd

  • มันอ่าน/dev/kmsgข้อมูลบันทึกเคอร์เนล
  • มันอ่าน/dev/log(ลิงก์สัญลักษณ์ไปที่/run/systemd/journal/dev-log) สำหรับข้อมูลบันทึกแอปพลิเคชันจากsyslog()ฟังก์ชั่นของไลบรารี GNU C
  • มันฟังบนAF_LOCALซ็อกเก็ตกระแสที่/run/systemd/journal/stdoutสำหรับข้อมูลบันทึกที่มาจากบริการที่มีการจัดการ systemd
  • มันฟังบนAF_LOCALซ็อกเก็ตเดตาแกรมที่/run/systemd/journal/socketสำหรับข้อมูลบันทึกที่มาจากโปรแกรมที่พูดถึงโปรโตคอลวารสารเฉพาะ systemd (เช่นsd_journal_sendv()et al.)
  • มันผสมสิ่งเหล่านี้เข้าด้วยกัน
  • มันเขียนถึงชุดของทั้งระบบและต่อผู้ใช้ไฟล์ที่บันทึกในหรือ/run/log/journal//var/log/journal/
  • ถ้ามันสามารถเชื่อมต่อ (เป็นไคลเอนต์) ไปยังAF_LOCALซ็อกเก็ตดาตาแกรมที่/run/systemd/journal/syslogมันเขียนข้อมูลวารสารที่นั่นถ้ามีการกำหนดค่าการส่งต่อไปยัง syslog
  • หากกำหนดค่ามันจะเขียนข้อมูลเจอร์นัลไปยังเคอร์เนลบัฟเฟอร์โดยใช้/dev/kmsgกลไกที่เขียนได้
  • หากกำหนดค่าไว้จะบันทึกข้อมูลเจอร์นัลไปยังเทอร์มินัลและอุปกรณ์คอนโซลด้วย

สิ่งไม่ดีเกิดขึ้นทั่วทั้งระบบหากโปรแกรมนี้ขัดข้องหรือหยุดให้บริการ

systemd เองจัดการสำหรับเอาท์พุทมาตรฐานและข้อผิดพลาดของบริการ (บางส่วน) ที่จะแนบกับ/run/systemd/journal/stdoutซ็อกเก็ต ดังนั้นผู้ที่เข้าสู่ระบบข้อผิดพลาดมาตรฐานในแบบปกติมีการส่งออกของพวกเขาไปยังวารสาร

สิ่งนี้แทนที่ทั้งหมด klogd, syslogd, syslog-ng และ rsyslogd

สิ่งเหล่านี้จำเป็นต้องเป็น systemd-specific บนระบบ systemd /dev/logพวกเขาไม่ได้ที่จะเป็นจุดสิ้นสุดของเซิร์ฟเวอร์ แต่พวกเขาใช้หนึ่งในสองวิธี:

  • พวกมันจะเป็นจุดสิ้นสุดของเซิร์ฟเวอร์/run/systemd/journal/syslogซึ่ง (ถ้าคุณจำได้) systemd-journaldจะพยายามเชื่อมต่อและเขียนข้อมูลวารสาร สองสามปีที่ผ่านมาหนึ่งจะกำหนดค่าimuxsockวิธีการป้อนข้อมูลของ rsyslogd ให้ทำเช่นนี้
  • พวกเขาอ่านโดยตรงจาก systemd journal โดยใช้ systemd-specific library ที่เข้าใจรูปแบบไบนารีวารสารและที่สามารถตรวจสอบไฟล์เจอร์นัลและไดเรกทอรีสำหรับรายการใหม่ที่ถูกเพิ่มเข้ามา ทุกวันนี้มีการกำหนดค่าimjournalวิธีการป้อนข้อมูลของ rsyslogd ให้ทำเช่นนี้
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.