ตัวอย่างที่ดีโดยใช้ java.util.logging [ปิด]


273

ฉันต้องการใช้บันทึกในโปรแกรมของฉัน ฉันได้ยินเกี่ยวกับjava.util.loggingแต่ฉันไม่รู้ว่าจะเริ่มอย่างไร

มีตัวอย่างของสิ่งที่ฉันจะทำอย่างไรกับการเข้าสู่ระบบ? ฉันจะใช้การบันทึกในโปรแกรมของตัวเองได้อย่างไร


7
คุณสามารถเริ่มต้นที่นี่: slf4j.org/manual.html
Jeremy

1
ฉันเห็นด้วยกับ Steven Vascellaro ฉันเบื่อที่เห็นรายการที่เป็นประโยชน์ถูกทำลายเนื่องจากการตรวจสอบหัวข้อไม่สิ้นสุด นอกจากนี้ขอแสดงความนับถือไม่เห็นด้วยกับเจเรมีตามที่ OP ถามเกี่ยวกับ java.util.logging ฉันสนใจการทำไม้พื้นเมืองด้วย (ขอบคุณสำหรับคำตอบ, grwww!)
NOP

ในการบันทึกข้อมูลในหนึ่งบรรทัด: log.log (Level.INFO, "ข้อความของฉัน {0}", วัตถุใหม่ [] {myDataId});
Mitja Gustin

คำตอบ:


335

java.util.logging ช่วยให้คุณไม่ต้องผูกไฟล์ jar อีกรอบด้วยแอปพลิเคชันของคุณและทำงานได้ดีกับฟอร์แมตเตอร์ที่ดี

โดยทั่วไปที่ด้านบนของทุกชั้นเรียนคุณควรจะมี:

private static final Logger LOGGER = Logger.getLogger( ClassName.class.getName() );

จากนั้นคุณสามารถใช้สิ่งอำนวยความสะดวกต่าง ๆ ของคลาสLogger


ใช้Level.FINEสำหรับทุกสิ่งที่ดีบั๊กที่ระดับสูงสุดของโฟลว์การดำเนินการ:

LOGGER.log( Level.FINE, "processing {0} entries in loop", list.size() );

ใช้Level.FINER/ Level.FINESTภายในของลูปและในสถานที่ที่คุณอาจไม่จำเป็นต้องเห็นรายละเอียดมากนักเมื่อทำการดีบั๊กปัญหาการไหลพื้นฐาน:

LOGGER.log( Level.FINER, "processing[{0}]: {1}", new Object[]{ i, list.get(i) } );

ใช้เวอร์ชันที่ทำพารามิเตอร์ของสิ่งอำนวยความสะดวกการบันทึกเพื่อป้องกันมิให้เกิดการสร้างการรวมสตริงแบบตันที่ GC จะต้องติดตาม Object[]เนื่องจากด้านบนมีราคาถูกในการจัดสรรสแต็กมักจะ


ด้วยการจัดการข้อยกเว้นให้บันทึกรายละเอียดข้อยกเว้นทั้งหมด:

try {
    ...something that can throw an ignorable exception
} catch( Exception ex ) {
    LOGGER.log( Level.SEVERE, ex.toString(), ex );
}

ฉันมักจะส่งผ่านex.toString()ข้อความที่นี่เพราะเมื่อฉัน " grep -n" สำหรับ " Exception" ในไฟล์บันทึกฉันก็สามารถเห็นข้อความได้เช่นกัน ไม่เช่นนั้นจะเกิดขึ้นในบรรทัดถัดไปของเอาต์พุตที่สร้างโดยสแต็กดัมพ์และคุณต้องมี RegEx ขั้นสูงเพื่อจับคู่บรรทัดนั้นด้วยซึ่งมักทำให้คุณได้รับเอาต์พุตมากกว่าที่คุณต้องมองผ่าน


3
สิ่งนี้เขียนไปยังไฟล์บางชนิดหรือไม่ ฉันยังใช้งานโปรแกรมไม่ได้ ฉันมีบรรทัดเริ่มต้นที่คุณมี แต่ยังไม่มีการทำงานใด ๆ
Doug Hauf

5
คุณดูบันทึกได้อย่างไร ห้องสมุดฉันใช้ต้น Logger วัตถุและใช้.fine()วิธีการในการเข้าสู่ระบบ แต่ฉันไม่สามารถดูเหมือนจะทำให้ข้อความแสดง ...
Anubian Noob

7
ฉันเขียนโปรแกรมใน Java ตั้งแต่ปี 1998 ฉันพบว่าการบันทึกใน Java มักจะปวดหัวมากกว่าที่จำเป็น นี่คือคำอธิบายที่ตรงไปตรงมาที่สุดในการเข้าสู่ระบบ Java ที่ฉันอ่าน รัดกุมเกินไป
Steve McLeod

30
เป็นที่น่าสนใจที่ไม่มีใครพูดถึงซึ่งสามารถค้นหาล็อกไฟล์ได้
Ahmedov

4
หากคุณสงสัยว่าไฟล์บันทึกอยู่ที่ใดตรวจสอบให้แน่ใจว่าคุณได้ตั้งค่าเครื่องจัดการสำหรับเครื่องบันทึก เมื่อต้องการส่งออกบันทึกไปยังคอนโซลใช้ ConsoleHandler ใหม่และเพิ่มสิ่งนี้ลงในตัวบันทึกของคุณโดยใช้วิธีการ addHandler ตรวจสอบให้แน่ใจว่าคุณเรียก setLevel ทั้งตัวบันทึกและตัวจัดการ
Craig Brown

67

ควรประกาศคนตัดไม้เช่นนี้:

private final static Logger LOGGER = Logger.getLogger(MyClass.class.getName());

ดังนั้นหากคุณปรับโครงสร้างชื่อชั้นของคุณใหม่

ผมเขียนบทความเกี่ยวกับคนตัดไม้ Java กับตัวอย่างที่นี่


53

มีตัวอย่างมากมายและประเภทต่าง ๆ สำหรับการบันทึก ดูแพ็คเกจjava.util.logging

รหัสตัวอย่าง:

import java.util.logging.Logger;

public class Main {

  private static Logger LOGGER = Logger.getLogger("InfoLogging");

  public static void main(String[] args) {
    LOGGER.info("Logging an INFO-level message");
  }
}

ไม่มีการเข้ารหัสฮาร์ดคลาสชื่อ :

import java.util.logging.Logger;

public class Main {
  private static final Logger LOGGER = Logger.getLogger(
    Thread.currentThread().getStackTrace()[0].getClassName() );

  public static void main(String[] args) {
    LOGGER.info("Logging an INFO-level message");
  }
}

15
ทำไมไม่ตั้งค่าชื่อที่บันทึกเป็นMain.class.getSimpleName()? เครื่องมือเปลี่ยนทางด้วยวิธีนี้จะเปลี่ยนแปลงได้อย่างถูกต้องหากจำเป็นและยังไม่เป็นวิธีแก้ปัญหาที่สองของคุณ
Pijusn

3
การทำ stacktrace สำหรับชื่อตัวบันทึกคือแฮ็ค, ช้าและไม่เป็นคัมภีร์ มันจะแตกและให้ชื่อแปลก ๆ แก่คุณสำหรับ AOP proxies หรือ byte coding extraordinaire
Adam Gent

9
-1 สำหรับธุรกิจ stacktrace ช้าและอาจป้องกันการเพิ่มประสิทธิภาพคอมไพเลอร์
phooji

4
เหตุใด "ความเชื่องช้า" จึงสำคัญเมื่อเริ่มต้นตัวบันทึก การกล่าวถึงความเชื่องช้าเป็นสิ่งที่คนส่วนใหญ่เรียกว่าการปรับให้เหมาะสมก่อนวัยอันควร (ใช่รหัสดูแฮ็คเล็กน้อย)
mikkom

3
@AndrewMcKinlay ในสถานการณ์อะไรมันแตกอะไร? หากแท็กคนตัดไม้ควรจะเป็นเช่นเดียวกับชื่อชั้นดูเหมือนว่าสมบูรณ์ดีที่จะทำ เครื่องมือการเปลี่ยนโครงสร้างกำลังจะเปลี่ยนชื่อโดยอัตโนมัติในขณะที่ถ้าเป็นสตริงที่กำหนดรหัสยากเครื่องมือการเปลี่ยนสถานะอาจข้ามไปหรือพูดว่า "คุณต้องการเปลี่ยนชื่อด้วยหรือไม่"
Pijusn

23

SLF4J เป็นส่วนการบันทึกที่ดีกว่า Apache Commons Logging (ACL) มีบริดจ์ไปยังเฟรมเวิร์กการบันทึกอื่น ๆ การโทรโดยตรงไปยัง ACL, Log4J หรือ Java Util Logging ผ่าน SLF4J เพื่อให้คุณสามารถส่งเอาต์พุตทั้งหมดไปยังไฟล์บันทึกไฟล์เดียวหากคุณต้องการโดยมีไฟล์กำหนดค่าบันทึกไฟล์เพียงไฟล์เดียว เหตุใดแอปพลิเคชันของคุณจะใช้เฟรมเวิร์กการบันทึกหลายเฟรม เนื่องจากห้องสมุดบุคคลที่สามที่คุณใช้โดยเฉพาะอย่างยิ่งห้องสมุดที่เก่ากว่า

SLF4J รองรับการใช้งานการบันทึกที่หลากหลาย มันสามารถส่งออกทุกอย่างเพื่อออกมาตรฐานใช้ Log4J หรือ Logback (แนะนำมากกว่า Log4J)

http://www.slf4j.org/

http://logback.qos.ch/


9

ฉันใช้minlogส่วนตัว มันง่ายมากเนื่องจากคลาสการบันทึกเป็นโค้ดสองสามร้อยบรรทัด


3
สำหรับรอยเท้าที่น้อยที่สุดนี่คือห้องสมุดให้เลือก
h3xStream

0

ฉันขอแนะนำให้คุณใช้ยูทิลิตี้การเข้าสู่ระบบของ Apache สามารถปรับขนาดได้สูงและรองรับไฟล์บันทึกแยกต่างหากสำหรับตัวบันทึกที่แตกต่างกัน ดูที่นี่


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