เกิดอะไรขึ้นกับการเข้าสู่ระบบใน Java? [ปิด]


117

เหตุใดจึงต้องใช้หนึ่งในแพ็คเกจต่อไปนี้แทนแพ็กเกจอื่น ๆ

  • การบันทึก Java
  • การบันทึกคอมมอนส์
  • log4j
  • SLF4J
  • Logback

4
คุณอาจต้องการstackoverflow.com/questions/873051ซึ่งเปรียบเทียบ SLF4j กับ Commons Logging
James McMahon

24
ทำไมนรกถึงสร้าง Ceki 3 logging framework !!! นั่นมันบ้า ...
mP

6
@mP - log4j เป็นครั้งแรกจากนั้นมีความขัดแย้งเกิดขึ้นและมีการเขียน slf4j + logback slf4j คือAPIและล็อกแบ็คการใช้งาน API โดยไม่คำนึงถึงสิ่งอื่นใด slf4j มีประโยชน์อย่างยิ่ง
Thorbjørn Ravn Andersen

3
สำหรับรายละเอียดเกี่ยวกับสาเหตุที่ Ceki Gülcüสร้าง SLF4J + Logback โปรดดูการพูดคุยของ Devoxx ต่อไปนี้: parleys.com/#st=5&id=1701
bitek

สิ่งที่ดีที่สุดที่จะออกมาคือ slf4j API ซึ่งหวังว่าจะรวมโลกแห่งการบันทึกเข้าด้วยกัน ฉันคิดว่าการบันทึกกลับยังไม่ประสบความสำเร็จอย่างมากกับนักพัฒนา
Thorbjørn Ravn Andersen

คำตอบ:


86

ตามลำดับเวลาของการปรากฏของ API (เท่าที่ฉันรู้):

  • Log4j เพราะทุกคนส่วนใหญ่ใช้มัน (จากประสบการณ์ของฉัน)
  • Commons Logging เนื่องจากโปรเจ็กต์โอเพ่นซอร์สใช้มัน (ดังนั้นจึงสามารถรวมเข้ากับเฟรมเวิร์กการบันทึกอะไรก็ได้ที่ใช้ในโซลูชันรวม) ใช้ได้โดยเฉพาะอย่างยิ่งหากคุณเป็น API / Framework / OSS และคุณต้องพึ่งพาแพ็คเกจอื่น ๆ ที่ใช้ Commons Logging
  • การบันทึกแบบคอมมอนส์เนื่องจากคุณไม่ต้องการ "ล็อก" ไว้ที่เฟรมเวิร์กการบันทึกโดยเฉพาะ (ดังนั้นคุณจะล็อกสิ่งที่ Commons Logging ให้คุณแทน) - ฉันไม่คิดว่าการตัดสินใจโดยใช้ประเด็นนี้เป็นเหตุผลนั้นสมเหตุสมผล
  • การบันทึก Java เนื่องจากคุณไม่ต้องการเพิ่มในโถพิเศษ
  • SLF4j เนื่องจากใหม่กว่า Commons Logging และมีการบันทึกแบบกำหนดพารามิเตอร์:

logger.debug("The entry is {}.", entry);
//which expands effectively to
if (logger.isDebugEnabled()){
    // Note that it's actually *more* efficient than this - see Huxi's comment below...
    logger.debug("The entry is " + entry + "."); 
}
  • Logback เพราะใหม่กว่า log4j และอีกครั้งรองรับการบันทึกแบบกำหนดพารามิเตอร์เนื่องจากใช้ SLF4j โดยตรง
  • SLF4j / Logback เพราะเขียนโดยผู้ชายคนเดียวกับที่ทำ log4j ดังนั้นเขาจึงทำได้ดีขึ้น (อ้างอิงจากKen G - ขอบคุณดูเหมือนว่าจะเหมาะสมเมื่อดูโพสต์ข่าวก่อนหน้านี้ )
  • SLF4j เนื่องจากพวกเขาเผยแพร่อะแด็ปเตอร์ log4j ด้วยดังนั้นคุณจึงไม่ต้อง "ปิด" log4j ในโค้ดรุ่นเก่าเพียงแค่ทำให้ log4j.properties ใช้ SLF4j และเป็นการกำหนดค่า

3
เท่าที่ฉันสามารถบอกได้ถึงแนวคิดเบื้องหลังการบันทึกคอมมอนส์คือควรใช้ในไลบรารี วิธีนี้ไลบรารีสามารถใช้กรอบการบันทึกเดียวกัน (ผ่านการบันทึกแบบคอมมอนส์) ที่แอปพลิเคชันโฮสติ้งใช้
Joachim Sauer

ขอขอบคุณ Loki สำหรับคำถาม ตอนนี้ฉันรู้แล้วว่าฉันจะไม่ใช้ log4j เป็นเฟรมเวิร์กเริ่มต้นอีกต่อไป SLF4j FTW! นอกจากนี้ขอบคุณ Ken G ที่ชี้ให้เห็นว่า SLF4j เขียนโดยผู้ชายคนเดียวกับ log4j
Stephen

3
ความคิดเห็นในตัวอย่างโค้ดของคุณไม่ถูกต้อง 100% การจัดรูปแบบข้อความจริงจะดำเนินการอย่างเฉื่อยชาโดย Logback ดังนั้นจะเกิดขึ้นก็ต่อเมื่อเหตุการณ์นั้นได้รับการจัดการโดย appender จริงๆและ appender ต้องการข้อความที่จัดรูปแบบซึ่งจะไม่เกิดขึ้นในกรณีเช่น SocketAppender เนื่องจากเหตุการณ์ถูกทำให้เป็นอนุกรมโดยใช้ รูปแบบข้อความที่ไม่เปลี่ยนแปลง + อาร์กิวเมนต์เป็น Strings ฉันเดาว่ามันขึ้นอยู่กับว่าคุณกำหนด "อย่างมีประสิทธิภาพ" อย่างไร แน่นอนมันจะส่งข้อความเดียวกัน (อย่างน้อยถ้ารายการและวัตถุเหมือนกัน;)) ดังนั้นโปรดยกโทษให้กับ nitpicking ของฉัน
Huxi

6
SLF4J เป็นเพียง API ที่อยู่ด้านบนของเฟรมเวิร์กการบันทึกอื่น ๆ คล้ายกับเป้าหมายของ Commons Logging แต่ใช้งานง่ายกว่าจากประสบการณ์ของฉัน
James McMahon

37

ฉันพบว่าการเข้าสู่ระบบ Java ทำให้สับสนไม่สอดคล้องกันเอกสารไม่ดีและโดยเฉพาะอย่างยิ่งส่งเดช นอกจากนี้ยังมีความคล้ายคลึงกันจำนวนมากระหว่างเฟรมเวิร์กการบันทึกเหล่านี้ซึ่งส่งผลให้เกิดความพยายามซ้ำซ้อนและเกิดความสับสนว่าคุณอยู่ในสภาพแวดล้อมการบันทึกแบบใดโดยเฉพาะอย่างยิ่งหากคุณกำลังทำงานในสแต็กเว็บแอ็พพลิเคชัน Java ที่ร้ายแรงคุณมักจะอยู่ในหลายอย่างการบันทึกสภาพแวดล้อมในครั้งเดียว (เช่น hibernate อาจใช้ log4j และ tomcat java.util.logging) Apache commons มีไว้เพื่อเชื่อมโยงเฟรมเวิร์กการบันทึกที่แตกต่างกัน แต่เพิ่มความซับซ้อนมากขึ้นเท่านั้น หากคุณไม่ทราบล่วงหน้าสิ่งนี้จะทำให้สับสนอย่างที่สุด เหตุใดข้อความบันทึกของฉันจึงไม่พิมพ์ออกมาที่คอนโซล ฯลฯ โอ้เพราะฉันกำลังดูบันทึก Tomcat ไม่ใช่ log4j การเพิ่มความซับซ้อนอีกชั้นหนึ่งแอ็พพลิเคชันเซิร์ฟเวอร์อาจมีการกำหนดค่าการบันทึกส่วนกลางที่อาจไม่รู้จักการกำหนดค่าภายในสำหรับเว็บแอปพลิเคชันเฉพาะ สุดท้ายนี้เฟรมเวิร์กการบันทึกทั้งหมดเหล่านี้เป็นวิธีที่ซับซ้อนเกินไป การเข้าสู่ระบบ Java เป็นเรื่องยุ่งเหยิงทำให้นักพัฒนาอย่างฉันหงุดหงิดและสับสน

Java เวอร์ชันก่อนหน้าไม่มีกรอบการบันทึกในตัวที่นำไปสู่สถานการณ์นี้


19
นี่คือคำตอบ? ดูเหมือนเป็นการพูดจาโผงผางมากกว่า
Michael Myers

15
ฉันขอโทษ. มันเป็นนิด ๆ หน่อย ๆ พูดจาโผงผาง แต่ยังเป็นการตอบสนองต่อ "What's Up with Logging in Java?" คำตอบสั้น ๆ คือมันแตกลึก
Julien Chastang

1
มันไม่คุ้มกับการโหวต -1; P แต่สิ่งที่ต้องไตร่ตรอง
guyumu

21
ปัญหาเริ่มต้นเมื่อ Sun เพิ่ม java.util.logging ลงใน Java 1.4 ก่อนหน้านั้น LOG4J เป็นที่ยอมรับและมีการใช้งานอย่างกว้างขวาง หลังจากนั้นก็มีความจำเป็นของเครื่องห่อเพื่อรองรับทั้ง LOG4J และ java.util.logging นอกจากนี้เนื่องจาก jul มีอยู่ในแพ็คเกจ java. * จึงไม่สามารถแทนที่ได้ด้วยการสลับ JAR ซึ่งเป็นวิธีที่ SLF4J เชื่อมโยงกับเฟรมเวิร์กอื่น ๆ นี่อาจเป็นความคิดที่แย่ที่สุดเท่าที่เคยมีมาของ Sun ... และในที่สุดมันก็นำไปสู่สมมติฐานที่ผิดว่า "พลเมืองชวาที่ดี" ควรใช้ jul
Huxi

4
@Huxi ฉันยืนยันว่า Calendar API แย่กว่า ในการป้องกัน Sun ไม่ใช่รหัสของพวกเขา แต่มาจาก Taglient
Thorbjørn Ravn Andersen

22

มีประเด็นสำคัญอย่างหนึ่งที่ไม่ได้กล่าวถึงมาก่อน:

SLF4J (และทั้ง Logback และ LOG4J เป็นแบ็กเอนด์การบันทึก) รองรับสิ่งที่เรียกว่า Mapped Diagnostic Context (MDC ดูjavadocและเอกสารประกอบ )

โดยพื้นฐานแล้วนี่คือแผนที่ <String, String> เธรด - โลคัลซึ่งคุณสามารถใช้เพื่อเพิ่มข้อมูลบริบทเพิ่มเติมให้กับเหตุการณ์การบันทึกของคุณ สถานะปัจจุบันของ MDC ติดอยู่กับทุกเหตุการณ์

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


2
ในทางเทคนิคแล้วมันเป็นแผนที่เธรดโลคัล <String, String>
pdxleif

17

ดูคำตอบของคำถามแนวทางปฏิบัติที่ดีที่สุดในการบันทึกข้อผิดพลาดคืออะไร โดยเฉพาะ:

  • มีปัญหาการโหลดคลาสที่อาจเกิดขึ้นกับ Commons Logging

  • Log4J และ SLF4J ได้รับการพัฒนาโดยบุคคลเดียวกันโดยเรียนรู้จากปัญหาที่พบในทางปฏิบัติด้วย Log4J


4

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

คุณสมบัติ LOG4j ทั้งหมดที่คุณสามารถเปลี่ยนได้ในไฟล์ log4j.properties ดังนั้นคุณสามารถใช้ไฟล์ที่แตกต่างกันสำหรับโปรเจ็กต์ต่างๆ

การบันทึก Java ไม่ใช่รายการโปรดของฉัน แต่อาจเป็นเพราะฉันใช้ log4j ตั้งแต่เริ่มต้น


4

ภาพรวมการเข้าสู่ระบบคอมมอนส์ให้เหตุผลสำหรับการดำรงอยู่ของมัน: การเข้าสู่ระบบจากโค้ดห้องสมุดเมื่อคุณมีการควบคุมมากกว่ากรอบการเข้าสู่ระบบพื้นฐานไม่มี สำคัญมากสำหรับโครงการ Apache ต่างๆซึ่งจะเชื่อมโยงกับแอปพลิเคชันภายนอก บางทีอาจไม่สำคัญสำหรับโครงการไอทีภายในซึ่งคุณสามารถควบคุมได้ทั้งหมด

ที่กล่าวว่าฉันเขียนถึง Commons Logging เช่นเดียวกับนักพัฒนาคนอื่น ๆ ที่ฉันรู้จัก เหตุผลก็คือเพื่อลดภาระทางจิตใจให้น้อยที่สุด: คุณสามารถเปลี่ยนโครงการหรืองานและไม่ต้องเรียนรู้กรอบงานใหม่ (หากงาน / โครงการใหม่ใช้ CL ด้วยและ / หรือคุณสามารถโน้มน้าวให้พวกเขาย้ายไปได้)

นอกจากนี้ยังมีคุณค่าในการสร้าง Wrapper ของคุณเองรอบ ๆ กรอบงานที่คุณใช้ ตามที่อธิบายไว้ที่นี่ฉันต้องการใช้อ็อบเจ็กต์ LogWrapper เพื่อจัดเตรียมสตริงที่กำหนดเอง (สำคัญ) และลดความยุ่งเหยิงของข้อความบันทึก (สำคัญน้อยกว่า)


1
นอกจากนี้ยังมี commons.logging => SLF4J bridge ซึ่งสามารถใช้เพื่อกำหนดเส้นทางการบันทึก CL ทั้งหมดผ่าน SLF4J SLF4J รองรับการเชื่อมโยง commons.logging, LOG4J และ (ค่อนข้างยุ่งยาก แต่ดีที่สุดเท่าที่จะทำได้) java.util.logging ดังนั้นบันทึกทั้งหมดจะลงเอยด้วยแบ็กเอนด์ SLF4J ที่คุณใช้ ดูslf4j.org/legacy.htmlฉันจะใช้ Logback, btw แต่คุณอาจเถียงว่าฉันลำเอียง
Huxi

2

โดยทั่วไปฉันจะใช้ Log4J เป็นค่าเริ่มต้น

ฉันจะใช้ Java Logging ถ้าฉันไม่สนใจการพึ่งพา Java 1.4 แต่ฉันยังคงใช้ Log4J ตามความต้องการ

ฉันจะใช้ Commons Logging ถ้าฉันกำลังปรับปรุงบางอย่างที่ใช้อยู่แล้ว


ไม่สนใจการพึ่งพา 1.4 หรือไม่? แม้ 1.4 จะสิ้นสุดอายุการใช้งาน
Tom Hawtin - แท็กไลน์

2
@ ทอมเขาหมายถึง jdk1.4 + อย่างี่เง่า
mP.

อันที่จริงฉันเพิ่งทำงานบางอย่างในระบบที่ยังทำงานภายใต้ jdk 1.3 :-( และเมื่อไม่ถึงสองปีที่แล้วฉันได้ดูแลระบบjdk 1.2ครั้งล่าสุดสถานที่มากเกินไปจะไม่อัปเกรดเว้นแต่จะมีอย่างแน่นอน พวกเขาปฏิเสธที่จะติดตั้งการอัปเกรดเท่านั้น
Michael Rutherfurd

0

ฉันขอแนะนำให้สร้างซุ้มการบันทึกแบบบางที่สามารถเขียนลงในเฟรมเวิร์กการบันทึกใด ๆ ณ จุดนั้นการเลือกเอนจินสำรองจะกลายเป็นจุดที่ค่อนข้างสงสัย


2
นั่นคือสิ่งที่การบันทึกคอมมอนส์ทำดังนั้นทำไมต้องสร้างวงล้อใหม่ นอกจากนี้ยังมีปัญหาบางอย่างที่ซุ้มของคุณจะต้องจัดการกับการบันทึกคอมมอนส์ที่ทำอยู่แล้ว
James AN Stauffer

+1 เพื่อต่อต้านข้อโต้แย้งการบันทึกคอมมอนแอปขององค์กรบางตัวใช้ตัวบันทึกแบบกำหนดเอง เป็นความคิดที่ดีเสมอที่จะซ่อนการนำไปใช้งาน กระดาษห่อหุ้ม 'แบบบาง' ช่วยลดความจำเป็นในการบรรจุขวดอีกใบและไม่มากเท่ากับการคิดค้นใหม่
questzen

1
สิ่งนี้ช่วยฉันได้เมื่อเร็ว ๆ นี้เมื่อเราพอร์ตกรอบงานของเราไปยัง Compact Framework (ใน. Net) หากเรามีการอ้างอิงแบบฮาร์ดโค้ดบน nLog เราคงจะเมาแล้ว เนื่องจากเราใช้แนวทางนี้เราจึงสามารถทิ้งคนตัดไม้ที่ว่างเปล่าและมีความสุขได้ มีคนโหวตฉันสำรองถึง 0 โปรด :-)
tsimon

3
มีอยู่แล้ว - ดูที่ slf4j เป็นกระดาษห่อหุ้มแบบบางที่ได้รับการยอมรับซึ่งช่วยให้คุณสามารถสลับกรอบการบันทึกเมื่อเริ่มต้นแอปพลิเคชันโดยการสลับไหบนคลาสพา ธ รันไทม์
ยับยั้ง

1
การอุดตันมีวิธีของตัวเองในการค้นหาว่าจะใช้กรอบอะไร - มันไม่ดีและค่อนข้างสับสน Ceki สร้างกรอบการบันทึกจำนวนเท่าใด คุณควรพยายามกำหนดระดับของการเชื่อมต่อระหว่างทิศทางและซ่อนการใช้งานแม้ว่าจะอุดตันด้วยการบันทึกของคุณเองก็ตาม เบื้องหลังคุณสามารถเสียบ f / w ที่คุณต้องการตามที่ Travis กล่าวไว้
mP.
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.