0Pricing
Java Academy · บทเรียน

ส่วนหน้าของ SLF4J และตัวบันทึก

บันทึกในระดับที่เหมาะสม

ส่วนหน้าของ SLF4J และตัวบันทึก เป็นบทเรียน Java Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Java Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Java Academy มีบทเรียนทั้งหมด 4 บทเรียน

SLF4J คืออะไร

SLF4J (ส่วนเชื่อมการบันทึกแบบง่ายสำหรับ Java) คือชั้นนามธรรม คุณเขียนโค้ดเรียกใช้ส่วนติดต่อของมัน แล้วระบบเบื้องหลังอย่าง Logback หรือ Log4j2 จะดำเนินการบันทึกล็อกจริง

วิธีนี้ทำให้ไลบรารีบันทึกล็อกได้โดยไม่บังคับให้แอปพลิเคชันใช้การนำไปใช้งานแบบใดแบบหนึ่ง

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Main {
    private static final Logger log = LoggerFactory.getLogger(Main.class);
    public static void main(String[] args) {
        log.info("Application started");
    }
}

การรับตัวบันทึก

สร้างตัวบันทึกหนึ่งตัวต่อหนึ่งคลาสด้วย LoggerFactory.getLogger(MyClass.class)

ตามธรรมเนียม ฟิลด์จะเป็น private static final และตั้งชื่อเป็น log หรือ logger ชื่อของคลาสจะกลายเป็นชื่อตัวบันทึก ซึ่งจะแสดงในผลลัพธ์

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class OrderService {
    private static final Logger log = LoggerFactory.getLogger(OrderService.class);
    void placeOrder(String id) {
        log.info("Placing order {}", id);
    }
}

ห้าระดับ

ตัวบันทึกของ SLF4J มีเมธอดหนึ่งเมธอดต่อหนึ่งระดับ:

  • log.trace(...)
  • log.debug(...)
  • log.info(...)
  • log.warn(...)
  • log.error(...)
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Main {
    private static final Logger log = LoggerFactory.getLogger(Main.class);
    public static void main(String[] args) {
        log.trace("entering main");
        log.debug("args length = {}", args.length);
        log.info("service is up");
        log.warn("cache miss");
        log.error("failed to connect");
    }
}

การเลือกระดับที่เหมาะสม

แนวทางมีดังนี้:

  • ERROR: ความล้มเหลวจริงที่มนุษย์ต้องตรวจสอบ
  • WARN: ความผิดปกติที่กู้คืนได้
  • INFO: เหตุการณ์สำคัญในวงจรชีวิต
  • DEBUG: ข้อมูลวินิจฉัยสำหรับนักพัฒนา ซึ่งปิดใช้งานในระบบจริง
  • TRACE: การติดตามที่มีรายละเอียดอย่างมาก
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class PaymentService {
    private static final Logger log = LoggerFactory.getLogger(PaymentService.class);
    void charge(int cents) {
        if (cents <= 0) { log.warn("non-positive charge: {}", cents); return; }
        log.info("charged {} cents", cents);
    }
}

ชื่อตัวบันทึกและลำดับชั้น

ชื่อตัวบันทึกมีลำดับชั้นตามแพ็กเกจที่คั่นด้วยจุด ตัวบันทึกชื่อ com.example.svc เป็นรายการย่อยของ com.example

การกำหนดค่าบนรายการหลักจะมีผลกับรายการย่อย เว้นแต่จะถูกกำหนดทับ ดังนั้นคุณจึงตั้งระดับแยกตามแพ็กเกจได้

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Main {
    public static void main(String[] args) {
        Logger a = LoggerFactory.getLogger("com.example.app");
        Logger b = LoggerFactory.getLogger("com.example.app.db");
        a.info("parent logger");
        b.debug("child inherits parent's level unless overridden");
    }
}

การป้องกันการเรียกใช้ที่ใช้ทรัพยากรมาก

สำหรับการสร้างข้อความที่ใช้ทรัพยากรมาก ให้ป้องกันด้วย isDebugEnabled() เพื่อให้การประมวลผลทำงานเฉพาะเมื่อระดับนั้นเปิดใช้งานอยู่

เมื่อใช้การบันทึกแบบมีพารามิเตอร์ในบทเรียนถัดไป คุณแทบไม่จำเป็นต้องทำเช่นนี้ แต่การป้องกันนี้จำเป็นเมื่อคุณสร้างสตริงด้วยตนเอง

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Main {
    private static final Logger log = LoggerFactory.getLogger(Main.class);
    static String heavyDump() { return "...large state..."; }
    public static void main(String[] args) {
        if (log.isDebugEnabled()) {
            log.debug("state: {}", heavyDump());
        }
    }
}

การบันทึกข้อยกเว้น

หากต้องการบันทึกข้อยกเว้นพร้อมการติดตามสแตกทั้งหมด ให้ส่ง Throwable เป็น อาร์กิวเมนต์สุดท้าย

อย่าใส่ข้อยกเว้นไว้ในตัวยึดตำแหน่ง ให้ส่งข้อยกเว้นหลังข้อความ

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Main {
    private static final Logger log = LoggerFactory.getLogger(Main.class);
    public static void main(String[] args) {
        try {
            throw new IllegalStateException("boom");
        } catch (Exception e) {
            log.error("Operation failed for id {}", 42, e);
        }
    }
}

ตัวบันทึกหนึ่งตัวต่อหนึ่งคลาส

ประกาศตัวบันทึกหนึ่งครั้งเป็นฟิลด์แบบ static final อย่าสร้างตัวบันทึกภายในเมธอด เพราะเป็นการเสียการประมวลผลและทำให้สูญเสียประโยชน์จากชื่อคลาส

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class UserRepository {
    // Good: one shared logger named after the class
    private static final Logger log = LoggerFactory.getLogger(UserRepository.class);
    void save(String user) { log.debug("saving {}", user); }
}

SLF4J กับระบบเบื้องหลัง

SLF4J เป็นเพียงส่วนติดต่อเท่านั้น เมื่อโปรแกรมทำงาน ส่วนติดต่อจะเชื่อมกับระบบเบื้องหลังใดก็ตามที่อยู่ในเส้นทางคลาส

  • เพิ่ม logback-classic: SLF4J จะใช้ Logback
  • เพิ่ม log4j-slf4j2-impl: SLF4J จะใช้ Log4j2

โค้ดของคุณไม่ต้องเปลี่ยนแปลง

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Main {
    private static final Logger log = LoggerFactory.getLogger(Main.class);
    public static void main(String[] args) {
        // Same code, different backend depending on classpath
        log.info("backend-agnostic logging");
    }
}

หลีกเลี่ยงการบันทึกข้อมูลที่ละเอียดอ่อน

อย่าบันทึกรหัสผ่าน โทเค็น หรือหมายเลขบัตรเครดิตแบบเต็มลงในล็อก ล็อกมักถูกส่งต่อไปยังหลายระบบและเก็บรักษาไว้เป็นเวลานาน

ให้ปกปิดหรือตัดฟิลด์ที่ละเอียดอ่อนออกก่อนบันทึกล็อก

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Main {
    private static final Logger log = LoggerFactory.getLogger(Main.class);
    static String mask(String card) { return "****" + card.substring(card.length() - 4); }
    public static void main(String[] args) {
        log.info("charged card {}", mask("4111111111111234"));
    }
}

บริการที่สมจริง

เมื่อนำทุกอย่างมารวมกัน: บริการขนาดเล็กที่บันทึกล็อกด้วยระดับที่เหมาะสมและมีเส้นทางจัดการข้อยกเว้น

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class EmailService {
    private static final Logger log = LoggerFactory.getLogger(EmailService.class);
    void send(String to) {
        log.debug("preparing email to {}", to);
        try {
            if (to == null) throw new IllegalArgumentException("null recipient");
            log.info("email sent to {}", to);
        } catch (Exception e) {
            log.error("failed to send email", e);
        }
    }
}

ตรวจสอบความเข้าใจ

ทดสอบความรู้พื้นฐานเกี่ยวกับ SLF4J

ทบทวน

คุณได้เรียนรู้เกี่ยวกับส่วนเชื่อม SLF4J:

  • รับ private static final Logger หนึ่งตัวต่อหนึ่งคลาส
  • ใช้เมธอดทั้งห้าระดับให้เหมาะสม
  • ชื่อตัวบันทึกมีลำดับชั้นเพื่อควบคุมแยกตามแพ็กเกจ
  • ส่ง Throwable เป็นอาร์กิวเมนต์สุดท้ายเพื่อบันทึกการติดตามสแตก และอย่าบันทึกข้อมูลลับ

ถัดไปคือข้อความแบบมีพารามิเตอร์ที่มีประสิทธิภาพ

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Main {
    private static final Logger log = LoggerFactory.getLogger(Main.class);
    public static void main(String[] args) {
        log.info("SLF4J facade recap complete");
    }
}

คำถามที่พบบ่อย

บทเรียน “ส่วนหน้าของ SLF4J และตัวบันทึก” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “ส่วนหน้าของ SLF4J และตัวบันทึก” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Java Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Java Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “ส่วนหน้าของ SLF4J และตัวบันทึก”

บันทึกในระดับที่เหมาะสม คุณปฏิบัติ Java Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Java Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Java Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน

บทเรียน “ส่วนหน้าของ SLF4J และตัวบันทึก” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Java Academy นี้ได้ไหม

ได้ บทเรียน Java Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. เหตุใดจึงควรใช้การบันทึกแบบมีโครงสร้าง
  2. ส่วนหน้าของ SLF4J และตัวบันทึก
  3. การบันทึกแบบกำหนดพารามิเตอร์
  4. การกำหนดค่า Logback
← กลับไปที่ Java Academy