สวัสดีทุกคนในชุมชน CodeGym!
![การบันทึก: อะไร อย่างไร ที่ไหน และด้วยอะไร - 1]()
วันนี้เรามาพูดถึงการบันทึก:
- มันคืออะไร ทำไมมันถึงมีอยู่ เมื่อไหร่ที่คุณควรใช้ เมื่อไหร่ที่คุณควรหลีกเลี่ยง
- การใช้งานการบันทึกใดบ้างที่มีอยู่ใน Java และสิ่งที่คุณควรทำกับตัวเลือกการบันทึกเหล่านี้ทั้งหมด
และบันทึกระดับ. เราจะหารือเกี่ยวกับตัวผนวกคืออะไรและวิธีกำหนดค่าอย่างถูกต้อง
- โหนดการบันทึกและวิธีกำหนดค่าให้ถูกต้องเพื่อให้ทุกอย่างทำงานตามที่เราต้องการ
เนื้อหานี้มีไว้สำหรับผู้ชมจำนวนมาก จะชัดเจนสำหรับทุกคนที่เพิ่งรู้จัก Java รวมถึงผู้ที่ทำงานแล้ว แต่เพิ่งสำรวจ
logger.info("log something");
Let's go!
ทำไมคุณต้องเข้าสู่ระบบ?
มาดูกรณีจริงที่การบันทึกช่วยแก้ปัญหาได้ นี่คือตัวอย่างจากงานของฉัน มีจุดที่แอปพลิเคชันรวมเข้ากับบริการอื่นๆ
ฉันใช้การบันทึกที่จุดเหล่านี้เพื่อสร้าง "ข้อแก้ตัว"ประเภทหนึ่ง: หากการผสานรวมใช้งานไม่ได้ ก็จะง่ายที่จะทราบว่าด้านใดมีปัญหา นอกจากนี้ยังแนะนำให้บันทึกข้อมูลสำคัญที่จัดเก็บไว้ในฐานข้อมูล ตัวอย่างเช่น การสร้างผู้ใช้ที่เป็นผู้ดูแลระบบ นี่เป็นสิ่งที่ดีในการเข้าสู่ระบบ
เครื่องมือสำหรับการเข้าสู่ระบบใน Java
ในบรรดาโซลูชันการบันทึกที่รู้จักกันดีใน Java เราสามารถเน้นสิ่งต่อไปนี้:
- Log4j
- กรกฎาคม — java.util.logging
- JCL — การบันทึกจาการ์ตาคอมมอนส์
- เข้าสู่ระบบ
- SLF4J — Facade การบันทึกอย่างง่ายสำหรับ Java
เราจะให้ภาพรวมของแต่ละรายการ จากนั้นเราจะใช้ การรวม slf4j - log4jเป็นพื้นฐานของการสนทนาเชิงปฏิบัติ ตอนนี้อาจดูแปลก แต่ไม่ต้องกังวล: ในตอนท้ายของบทความทุกอย่างจะชัดเจน |
System.err.println
ในตอนแรกมี
System.err.println (แสดงรายการบันทึกบนคอนโซล) แม้กระทั่งทุกวันนี้ เทคนิคนี้ใช้เพื่อบันทึกอย่างรวดเร็วเมื่อทำการดีบัก แน่นอนว่าไม่มีการตั้งค่าที่จะพูดคุยที่นี่ ดังนั้นจำวิธีการนี้ไว้ แล้วเราจะดำเนินการต่อไป
Log4j
นี่เป็นโซลูชันที่สมบูรณ์ที่นักพัฒนาสร้างขึ้นจากความจำเป็น ผลที่ได้คือเครื่องมือที่น่าสนใจที่คุณสามารถใช้ได้ เนื่องจากสถานการณ์ต่างๆ การแก้ปัญหานี้ไม่ได้จบลงที่ JDK ซึ่งเป็นข้อเท็จจริงที่ทำให้ทั้งชุมชนไม่พอใจอย่างมาก Log4j มีตัวเลือกการกำหนดค่าที่ให้คุณเปิดใช้งานการบันทึกใน
com.example.type
แพ็คเกจและปิดใน
com.example.type.generic
แพ็คเกจย่อย ทำให้สามารถแยกรหัสที่ไม่จำเป็นต้องบันทึกออกได้อย่างรวดเร็ว โปรดทราบว่า
Log4j มีสองเวอร์ชัน: 1.2.x และ 2.xx และทั้งสองเวอร์ชันเข้ากันไม่ได้ Log4j เพิ่มแนวคิดของ
appender(เครื่องมือที่ใช้ในการเขียนบันทึก) และเลย์เอาต์ (การจัดรูปแบบบันทึก) สิ่งนี้ช่วยให้คุณบันทึกเฉพาะสิ่งที่คุณต้องการและบันทึกตามที่คุณต้องการ เราจะพูดถึง appender เพิ่มเติมในภายหลัง
กรกฎาคม — java.util.logging
ข้อดีอย่างหนึ่งของโซลูชันนี้คือ JUL รวมอยู่ใน JDK (Java Development Kit) น่าเสียดายที่เมื่อได้รับการพัฒนา ผู้สร้างไม่ได้อิงตามยูทิลิตี Log4j ที่เป็นที่นิยม แต่เป็นโซลูชันจาก IBM การตัดสินใจนั้นมีผลตามมา ความจริงก็คือตอนนี้ไม่มีใครใช้ JUL ระดับการบันทึกใน JUL แตกต่างจากที่ Logback, Log4j และ Slf4j มี สิ่งนี้ทำให้พวกเขาเข้าใจกันได้ยากขึ้น การสร้างคนตัดไม้นั้นคล้ายกันมากหรือน้อย ในการทำเช่นนี้ คุณต้องทำการอิมพอร์ต:
java.util.logging.Logger log = java.util.logging.Logger.getLogger(LoggingJul.class.getName());
มีการส่งผ่านชื่อคลาส ดังนั้นเราจึงรู้ว่าการบันทึกของเราจะมาจากไหน เริ่มต้นด้วย Java 8 คุณสามารถผ่าน
Supplier<String>
. สิ่งนี้ช่วยให้เราอ่านและสร้างบรรทัดเฉพาะเมื่อเราต้องการจริงๆ แทนที่จะทุกครั้งเหมือนที่เคยเป็นมา ด้วยการเปิดตัว Java 8 เท่านั้น ในที่สุดนักพัฒนาก็แก้ปัญหาที่สำคัญและทำให้ JUL ใช้งานได้จริง ได้แก่ วิธีการที่มี
Supplier<String> msgSupplier
พารามิเตอร์ดังที่แสดงด้านล่าง:
public void info(Supplier<String> msgSupplier) {
log(Level.INFO, msgSupplier);
}
JCL — การบันทึกจาการ์ตาคอมมอนส์
เนื่องจากไม่มีมาตรฐานอุตสาหกรรมเกี่ยวกับการบันทึกมาเป็นเวลานาน และหลายคนสร้างเครื่องบันทึกแบบกำหนดเองของตนเอง จึงตัดสินใจเปิดตัว JCL ซึ่งเป็นเครื่องห่อทั่วไปที่สามารถใช้กับเครื่องบันทึกอื่นๆ ได้ ทำไม บางครั้งการขึ้นต่อกันที่เพิ่มลงในโปรเจ็กต์จะใช้ตัวบันทึกที่แตกต่างจากตัวที่อยู่ในโปรเจ็กต์ ด้วยเหตุนี้ พวกเขาจึงถูกเพิ่มเข้าไปในโปรเจ็กต์เป็นการพึ่งพาสกรรมกริยา และสร้างปัญหาที่แท้จริงเมื่อพยายามรวบรวมทั้งหมดเข้าด้วยกัน น่าเสียดายที่กระดาษห่อหุ้มนั้นใช้งานไม่ได้มากและไม่ได้เพิ่มอะไรเลย คงจะสะดวกถ้าทุกคนใช้ JCL แต่นั่นไม่ใช่สิ่งที่เกิดขึ้น ดังนั้นการใช้ JCL จึงไม่ใช่แนวคิดที่ดีที่สุดในขณะนี้
เข้าสู่ระบบ
เส้นทางโอเพ่นซอร์สนั้นยุ่งยาก... นักพัฒนาคนเดียวกับที่เขียน Log4j ยังเขียน Logback เป็นกรอบการบันทึกที่สืบทอดมา มันขึ้นอยู่กับแนวคิดเดียวกันกับ Log4j ความแตกต่างในการ Logback คือ:
- ปรับปรุงประสิทธิภาพ
- เพิ่มการรองรับดั้งเดิมสำหรับ Slf4j
- ตัวเลือกการกรองแบบขยาย
ตามค่าเริ่มต้น Logback ไม่ต้องการการกำหนดค่าใดๆ และบันทึกเหตุการณ์ทั้งหมดที่ระดับ DEBUG และสูงกว่า หากคุณต้องการการปรับแต่ง คุณสามารถทำได้ผ่านการกำหนดค่า XML:
<configuration>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>app.log</file>
<encoder>
<pattern>%d{HH:mm:ss,SSS} %-5p [%c] - %m%n</pattern>
</encoder>
</appender>
<logger name="org.hibernate.SQL" level="DEBUG" />
<logger name="org.hibernate.type.descriptor.sql" level="TRACE" />
<root level="info">
<appender-ref ref="FILE" />
</root>
</configuration>
SLF4J — Facade การบันทึกอย่างง่ายสำหรับ Java
ในช่วงปี 2549 หนึ่งในผู้ก่อตั้ง Log4j ออกจากโปรเจ็กต์และสร้าง Slf4j (Simple Logging Facade สำหรับ Java) ซึ่งเป็น wrapper สำหรับ Log4j, JUL, Common-logging และ Logback อย่างที่คุณเห็น เราได้ก้าวไปสู่จุดของการสร้าง wrapper บน wrapper... ในกรณีนี้ จะแบ่งออกเป็นสองส่วน: API ที่ใช้ในแอปพลิเคชัน และการใช้งานที่เพิ่มเข้ามาโดยแยกจากกัน การพึ่งพาสำหรับการบันทึกแต่ละประเภท ตัวอย่างเช่น
slf4j-log4j12.jar
และ
slf4j-jdk14.jar
. คุณต้องเชื่อมต่อการใช้งานที่ถูกต้อง เพียงเท่านี้โครงการทั้งหมดของคุณก็จะใช้งานได้ Slf4j รองรับคุณสมบัติล่าสุดทั้งหมด เช่น การจัดรูปแบบสตริงสำหรับการบันทึก ก่อนหน้านี้มีปัญหาดังกล่าว สมมติว่าเราสร้างรายการบันทึกดังนี้:
log.debug("User " + user + " connected from " + request.getRemoteAddr());
เนื่องจากตัวดำเนินการเชื่อมข้อมูล
user
วัตถุจึงกลายเป็นสตริงอย่างเงียบ ๆ ต้อง
user.toString()
ขอบคุณ สิ่งนี้ต้องใช้เวลาและทำให้ระบบช้าลง และนั่นอาจไม่เป็นไรหากเรากำลังดีบักแอปพลิเคชัน เราเริ่มพบปัญหาหากระดับล็อกสำหรับคลาสนี้เป็น INFO หรือสูงกว่า กล่าวอีกนัยหนึ่ง เราไม่ควรเขียนรายการบันทึกนี้ (สำหรับ INFO หรือสูงกว่า) และไม่ควรใช้การต่อสตริง ตามทฤษฎีแล้ว ไลบรารีการบันทึกควรจัดการเรื่องนี้เอง สิ่งนี้กลายเป็นปัญหาที่ใหญ่ที่สุดใน Log4j เวอร์ชันแรก มันไม่ได้ให้วิธีแก้ปัญหาที่ดี แต่แนะนำให้ทำสิ่งนี้แทน:
if (log.isDebugEnabled()) {
log.debug("User " + user + " connected from " + request.getRemoteAddr());
}
นั่นคือ แทนที่จะเขียนโค้ดหนึ่งบรรทัดสำหรับการบันทึก พวกเขาแนะนำให้เขียน 3! การบันทึกควรลดการเปลี่ยนแปลงโค้ดให้น้อยที่สุด และบรรทัดสามบรรทัดละเมิดแนวทางทั่วไปนั้นอย่างชัดเจน Slf4j ไม่มีปัญหาความเข้ากันได้กับ JDK และ API ดังนั้นจึงมีวิธีแก้ปัญหาที่ดีทันที:
log.debug("User {} connected from {}", user, request.getRemoteAddr());
โดยที่
{}
แสดงถึงตัวยึดสำหรับอาร์กิวเมนต์ที่ส่งผ่านไปยังเมธอด นั่นคือ อันแรก
{}
ตรงกับ
user
และอันที่สอง
{}
ตรง
request.getRemoteAddr()
กับ เมื่อทำเช่นนี้ เราจะดำเนินการต่อสตริงต่อเมื่อระดับบันทึกต้องการให้เราเขียนรายการบันทึกเท่านั้น หลังจากนั้น Sjf4j ก็เริ่มได้รับความนิยมเพิ่มขึ้นอย่างรวดเร็ว ปัจจุบันเป็นทางออกที่ดีที่สุด ดังนั้น มาดูการบันทึกโดยใช้
slf4j-log4j12
การเชื่อมโยง กัน
สิ่งที่ต้องเข้าสู่ระบบ
แน่นอน คุณไม่ควรบันทึกทุกอย่าง สิ่งนี้มักไม่จำเป็นและบางครั้งก็เป็นอันตราย ตัวอย่างเช่น หากคุณบันทึกข้อมูลส่วนตัวของใครบางคนและข้อมูลนั้นรั่วไหลออกมา จะเกิดปัญหาขึ้นจริง โดยเฉพาะอย่างยิ่งในโครงการที่เน้นไปที่ตลาดตะวันตก แต่ยังมี
สิ่งที่คุณควรบันทึกอย่างแน่นอน :
- เริ่มต้น / สิ้นสุดของแอปพลิเคชัน เราจำเป็นต้องทราบว่าแอปพลิเคชันเริ่มต้นและสิ้นสุดจริงตามที่คาดไว้หรือไม่
- ปัญหาด้านความปลอดภัย. ที่นี่ เป็นการดีที่จะบันทึกความพยายามในการเดารหัสผ่านของใครบางคน กรณีเมื่อผู้ดูแลระบบลงชื่อเข้าใช้ ฯลฯ
- สถานะของแอปพลิเคชันบางอย่าง ตัวอย่างเช่น การเปลี่ยนจากสถานะหนึ่งไปยังอีกสถานะหนึ่งในกระบวนการทางธุรกิจ
- ข้อมูลการดีบักบางอย่างพร้อมกับระดับบันทึกที่เกี่ยวข้อง
- สคริปต์ SQL บางตัว มีกรณีในโลกแห่งความเป็นจริงเมื่อสิ่งนี้จำเป็น แต่อีกครั้งด้วยการปรับระดับการบันทึกอย่างชำนาญ คุณจะได้ผลลัพธ์ที่ยอดเยี่ยม
- สามารถบันทึกการรันเธรด เมื่อตรวจสอบว่าสิ่งต่าง ๆ ทำงานได้อย่างถูกต้อง
ข้อผิดพลาดยอดนิยมในการบันทึก
มีความแตกต่างมากมายที่นี่ แต่เราจะกล่าวถึงข้อผิดพลาดทั่วไปบางประการเป็นพิเศษ:
- การบันทึกที่มากเกินไป คุณไม่ควรบันทึกทุกขั้นตอนที่อาจมีความสำคัญในทางทฤษฎี หลักการทั่วไปที่ดี: บันทึกไม่ควรเกิน 10% ของโหลด มิฉะนั้นจะมีปัญหาด้านประสิทธิภาพ
- บันทึกข้อมูลทั้งหมดลงในไฟล์เดียว ในบางจุด สิ่งนี้จะทำให้อ่าน/เขียนบันทึกได้ยากมาก ไม่ต้องพูดถึงข้อเท็จจริงที่ว่าบางระบบมีการจำกัดขนาดไฟล์
- ใช้ระดับการบันทึกที่ไม่ถูกต้อง บันทึกแต่ละระดับมีขอบเขตที่ชัดเจนและควรเคารพ หากขอบเขตไม่ชัดเจน คุณสามารถตกลงกันได้ว่าจะใช้ระดับใด
บันทึกระดับ
|
|
|
x: มองเห็นได้ |
|
|
|
|
ร้ายแรง |
ข้อผิดพลาด |
เตือน |
ข้อมูล |
ดีบัก |
ติดตาม |
ทั้งหมด |
ปิด |
|
|
|
|
|
|
|
ร้ายแรง |
x |
|
|
|
|
|
|
ข้อผิดพลาด |
x |
x |
|
|
|
|
|
เตือน |
x |
x |
x |
|
|
|
|
ข้อมูล |
x |
x |
x |
x |
|
|
|
ดีบัก |
x |
x |
x |
x |
x |
|
|
ติดตาม |
x |
x |
x |
x |
x |
x |
|
ทั้งหมด |
x |
x |
x |
x |
x |
x |
x |
ระดับการบันทึกคืออะไร? เพื่อที่จะสร้างลำดับชั้นของรายการบันทึก ข้อตกลงและการกำหนดขอบเขตบางอย่างเป็นสิ่งที่จำเป็น นี่คือเหตุผลที่แนะนำระดับการบันทึก มีการตั้งค่าระดับในแอปพลิเคชัน หากรายการอยู่ต่ำกว่าระดับที่ระบุ รายการนั้นจะไม่ถูกบันทึก ตัวอย่างเช่น เรามีบันทึกที่เราใช้เมื่อแก้ไขข้อบกพร่องของแอปพลิเคชัน ระหว่างการทำงานปกติ (เมื่อแอปพลิเคชันถูกใช้ตามวัตถุประสงค์) ไม่จำเป็นต้องใช้บันทึกดังกล่าว ดังนั้น ระดับการบันทึกจึงสูงกว่าสำหรับการดีบัก มาดูระดับการบันทึกโดยใช้ Log4j นอกเหนือจาก JUL แล้ว โซลูชันอื่นๆ ยังใช้ระดับบันทึกเดียวกัน ที่นี่พวกเขาอยู่ในลำดับที่ลดลง:
- ปิด:ไม่มีการบันทึกรายการบันทึก; ทุกอย่างถูกละเว้น
- FATAL:ข้อผิดพลาดที่ทำให้แอปพลิเคชันไม่สามารถทำงานต่อไปได้ ตัวอย่างเช่น "ข้อผิดพลาด JVM หน่วยความจำไม่เพียงพอ"
- ข้อผิดพลาด:ข้อผิดพลาดในระดับนี้บ่งบอกถึงปัญหาที่ต้องได้รับการแก้ไข ข้อผิดพลาดไม่ได้หยุดแอปพลิเคชันโดยรวม คำขออื่นๆ อาจทำงานได้อย่างถูกต้อง
- WARN:รายการบันทึกที่แสดงคำเตือน มีบางอย่างที่ไม่คาดคิดเกิดขึ้น แต่ระบบก็สามารถรับมือและทำตามคำขอได้
- ข้อมูล:รายการบันทึกที่ระบุการดำเนินการที่สำคัญในแอปพลิเคชัน นี่ไม่ใช่ข้อผิดพลาดหรือคำเตือน เป็นเหตุการณ์ของระบบที่คาดไว้
- DEBUG:รายการบันทึกจำเป็นต้องดีบักแอปพลิเคชัน เพื่อให้แน่ใจว่าแอปพลิเคชันทำในสิ่งที่คาดหวัง หรือเพื่ออธิบายการดำเนินการของแอปพลิเคชัน เช่น "ป้อน method1"
- TRACE:รายการบันทึกที่มีลำดับความสำคัญต่ำกว่าสำหรับการดีบัก ระดับบันทึกต่ำสุด
- ทั้งหมด:ระดับบันทึกสำหรับเขียนรายการบันทึกทั้งหมดของแอปพลิเคชัน
ในระดับบันทึกของ INFO เปิดใช้งานอยู่ที่ใดที่หนึ่งในแอปพลิเคชัน จากนั้นรายการสำหรับทุกระดับจะถูกบันทึก ตั้งแต่ INFO ถึง FATAL หากตั้งค่าระดับบันทึก FATAL จะมีการเขียนเฉพาะรายการบันทึกที่มีระดับนั้น
การบันทึกและการส่งบันทึก: ภาคผนวก
ลองพิจารณาว่าทั้งหมดนี้ทำงานอย่างไรเมื่อเราใช้ Log4j ซึ่งให้โอกาสมากมายในการเขียน/ส่งบันทึก:
- เพื่อเขียนลงไฟล์ —
DailyRollingFileAppender
- เพื่อเขียนข้อมูลไปยังคอนโซล —
ConsoleAppender
- เพื่อเขียนบันทึกลงในฐานข้อมูล —
JDBCAppender
- เพื่อจัดการการส่งบันทึกผ่าน TCP/IP —
TelnetAppender
- เพื่อให้แน่ใจว่าการบันทึกจะไม่ส่งผลเสียต่อประสิทธิภาพ —
AsyncAppender
มีการใช้งานเพิ่มเติมอีกสองสามรายการ: รายการทั้งหมดมีอยู่ที่
นี่ อย่างไรก็ตาม ถ้าไม่มี appender ที่คุณต้องการ นั่นก็ไม่มีปัญหา คุณสามารถเขียน appender ของคุณเองได้โดยใช้ อินเทอร์เฟ
ซ Appenderซึ่ง Log4j รองรับ
โหนดการบันทึก
เพื่อจุดประสงค์ในการสาธิต เราจะใช้อินเทอร์เฟซ Slf4j โดยมีการใช้งานจาก Log4j การสร้างตัวบันทึกทำได้ง่ายมาก ในคลาสชื่อ
MainDemo
ซึ่งจะทำการบันทึกบางอย่าง เราจำเป็นต้องเพิ่มสิ่งต่อไปนี้:
org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(MainDemo.class);
สิ่งนี้จะสร้างคนตัดไม้ให้กับเรา ในการสร้างรายการบันทึก มีหลายวิธีที่ใช้ได้ซึ่งชื่อสะท้อนถึงระดับบันทึกที่จะใช้ ตัวอย่างเช่น:
logger.trace("Method 1 started with argument={}", argument);
logger.debug("Database updated with script = {}", script);
logger.info("Application has started on port = {}", port);
logger.warn("Log4j didn't find the log4j.properties file. Please fix this.");
logger.error("Connection refused to host = {}", host);
แม้ว่าเราจะผ่านชั้นเรียน แต่ชื่อสุดท้ายคือชื่อเต็มของชั้นเรียนรวมถึงแพ็คเกจ สิ่งนี้ทำเพื่อให้ในภายหลังคุณสามารถแบ่งการบันทึกออกเป็นโหนดและกำหนดค่าระดับการบันทึกและ appender สำหรับแต่ละโหนด ตัวอย่างเช่น คนตัดไม้ถูกสร้างขึ้นใน
com.github.romankh3.logginglecture.MainDemo
ชั้นเรียน ชื่อนี้เป็นพื้นฐานสำหรับการสร้างลำดับชั้นของโหนดการบันทึก โหนดหลักคือ RootLogger ระดับบน
สุด นี่คือโหนดที่รับรายการบันทึกทั้งหมดสำหรับแอปพลิเคชันทั้งหมด โหนดที่เหลือสามารถอธิบายได้ดังที่แสดงด้านล่าง:
![การบันทึก: อะไร อย่างไร ที่ไหน และด้วยอะไร - 3]()
ส่วนต่อท้ายได้รับการกำหนดค่าสำหรับโหนดการบันทึกเฉพาะ ตอนนี้เราจะดูที่ ไฟล์
log4j.propertiesเพื่อดูตัวอย่างวิธีกำหนดค่า
คำแนะนำทีละขั้นตอนสำหรับไฟล์ log4j.properties
เราจะตั้งค่าทุกอย่างทีละขั้นตอนและดูว่าอะไรเป็นไปได้:
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
บรรทัดนี้ระบุว่าเรากำลังลงทะเบียน appender ของ CONSOLE ซึ่งใช้ org.apache.log4j.ConsoleAppender appender นี้เขียนข้อมูลไปยังคอนโซล ต่อไปเราจะลงทะเบียนผู้ต่อท้ายรายอื่น อันนี้จะเขียนไปยังไฟล์:
log4j.appender.FILE=org.apache.log4j.RollingFileAppender
สิ่งสำคัญคือต้องทราบว่าส่วนต่อท้ายยังคงต้องได้รับการกำหนดค่า เมื่อเราลงทะเบียนผู้ผนวกแล้ว เราสามารถกำหนดระดับการบันทึกและผู้ผนวกที่จะใช้ที่โหนด
log4j.rootLogger=ดีบัก คอนโซล ไฟล์
- log4j.rootLogger หมายความว่าเรากำลังกำหนดค่าโหนดรูท ซึ่งมีรายการบันทึกทั้งหมด
- คำแรกหลังเครื่องหมายเท่ากับหมายถึงระดับการบันทึกขั้นต่ำที่จะเขียน (ในกรณีของเรา มันคือ DEBUG)
- ตามเครื่องหมายจุลภาค เราระบุส่วนต่อท้ายทั้งหมดที่จะใช้
หากต้องการกำหนดค่าโหนดการบันทึกเฉพาะเจาะจงมากขึ้น คุณจะต้องใช้รายการดังนี้:
log4j.logger.com.github.romankh3.logginglecture=TRACE, OWN, CONSOLE
โดย
log4j.logger.
ที่ใช้เพื่ออ้างอิงโหนดเฉพาะ ในกรณีของเรา
com.github.romankh3.logginglecture.
ตอนนี้เรามาพูดถึงการกำหนดค่า appender ของ CONSOLE:
# CONSOLE appender customization
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.threshold=DEBUG
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=[%-5p] : %c:%L : %m%n
ที่นี่เราเห็นว่าเป็นไปได้ที่จะกำหนดระดับเฉพาะที่ appender จะเริ่มทำงาน นี่คือตัวอย่างของสิ่งที่เกิดขึ้นจริง: สมมติว่าโหนดบันทึกได้รับข้อความที่มีระดับ INFO และส่งผ่านไปยังส่วนต่อท้ายที่ได้รับมอบหมาย หากเกณฑ์ของผู้ผนวกถูกตั้งค่าเป็น WARN จะได้รับรายการบันทึกแต่ไม่ได้ทำอะไรเลย ต่อไป เราต้องตัดสินใจว่าข้อความจะใช้เค้าโครงใด ฉันใช้ PatternLayout ในตัวอย่าง แต่มีตัวเลือกอื่นๆ อีกมากมาย เราจะไม่กล่าวถึงสิ่งเหล่านี้ในบทความนี้ ตัวอย่างการกำหนดค่าส่วนต่อท้าย FILE:
# File appender customization
log4j.appender.FILE=org.apache.log4j.RollingFileAppender
log4j.appender.FILE.File=./target/logging/logging.log
log4j.appender.FILE.MaxFileSize=1MB
log4j.appender.FILE.threshold=DEBUG
log4j.appender.FILE.MaxBackupIndex=2
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.ConversionPattern=[ %-5p] - %c:%L - %m%n
คุณสามารถกำหนดค่าไฟล์เฉพาะที่จะเขียนรายการบันทึกดังที่เห็นได้จากบรรทัดนี้:
log4j.appender.FILE.File=./target/logging/logging.log
รายการถูกเขียนลงใน
logging.log
ไฟล์ เพื่อหลีกเลี่ยงปัญหาเกี่ยวกับขนาดไฟล์ คุณสามารถกำหนดค่าสูงสุด ซึ่งในกรณีนี้คือ 1MB
MaxBackupIndex
ระบุว่าจะมีไฟล์บันทึกดังกล่าวกี่ไฟล์ หากเราต้องการสร้างไฟล์มากกว่านี้ ไฟล์แรกจะถูกลบ หากต้องการดูตัวอย่างจริงที่มีการกำหนดค่าการบันทึก คุณสามารถไปที่
ที่เก็บสาธารณะบน GitHub
ตอกย้ำสิ่งที่เราได้คุยกัน
ลองทำทุกสิ่งที่เราอธิบายด้วยตัวคุณเอง:
- สร้างโครงการของคุณเองคล้ายกับตัวอย่างด้านบน
- หากคุณรู้วิธีใช้ Maven ให้ใช้มัน ถ้าไม่ ให้อ่าน บทช่วยสอน นี้ซึ่งอธิบายวิธีการเชื่อมต่อไลบรารี
สรุป
- เราได้พูดคุยเกี่ยวกับโซลูชันการบันทึกที่มีอยู่ใน Java
- ไลบรารีการบันทึกที่รู้จักกันดีเกือบทั้งหมดเขียนโดยคนคนเดียว :D
- เราได้เรียนรู้ว่าอะไรควรและไม่ควรเข้าสู่ระบบ
- เราพบระดับบันทึก
- เราได้รับการแนะนำให้รู้จักกับโหนดการบันทึก
- เราดูว่า appender คืออะไรและมีไว้เพื่ออะไร
- เราสร้างไฟล์ log4j.proterties ทีละขั้นตอน
วัสดุเพิ่มเติม
- CodeGym: บทเรียน Logger
- Geekly รายสัปดาห์: การบันทึก Java สวัสดีชาวโลก
- การเขียนโค้ดสยองขวัญ: ปัญหาเกี่ยวกับการบันทึก
- YouTube: ทำความเข้าใจ Java Logging Hell - พื้นฐาน Java Logging Hell & วิธีหลีกเลี่ยง
- Log4j: ผู้ผนวก
- Log4j: เค้าโครง
ดูบทความอื่นของฉันด้วย:
GO TO FULL VERSION