Timber — คืออะไร API ของไลบรารีและตัวอย่างการใช้งาน

ผู้แต่ง: IT Sectr เผยแพร่เมื่อ: 2026-05-28 เวลาอ่าน: 8 นาที

Timber เป็นไลบรารีการบันทึกที่มีน้ำหนักเบาสำหรับ Android ที่มีสถาปัตยกรรมที่ขยายได้แบบต้นไม้ (Tree) ซึ่งแทนที่ android.util.Log มาตรฐานในโปรเจกต์นับพัน ตามข้อมูลจาก GitHub, 2024 ไลบรารีได้รับดาวมากกว่า 10,000 ดวงและถูกใช้ในแอปพลิเคชันที่มีการติดตั้งมากกว่า 1 พันล้านครั้ง Timber แก้ปัญหาหลักสามประการของ Log API: การขาด tag อัตโนมัติ, การตรวจสอบ isLoggable ที่จำเป็น และลักษณะคงที่ของการเรียก

ประเด็นสำคัญ

  • Timber — ตัวหุ้มบน android.util.Log ที่มีการตรวจจับ tag อัตโนมัติตามชื่อคลาสและสแต็กการเรียก
  • Tree — องค์ประกอบพื้นฐานของสถาปัตยกรรม Timber แต่ละอินสแตนซ์กำหนดวิธีการประมวลผลข้อความบันทึก
  • การปลูกต้นไม้ — กระบวนการลงทะเบียน Tree ใน Timber โดยปกติทำครั้งเดียวใน Application.onCreate
  • DebugTree — การใช้งานในตัวสำหรับบิลด์ Debug ส่งออกบันทึกไปยัง Logcat ด้วยชื่อคลาสเป็น tag
  • Custom Tree — ความสามารถในการสร้างการใช้งานของคุณเองเพื่อส่งบันทึกไปยัง Crashlytics, ไฟล์ หรือเซิร์ฟเวอร์

Timber คืออะไร

Timber เป็นไลบรารีโอเพนซอร์สสำหรับ Android ที่สร้างโดย Jake Wharton ในปี 2013 เพื่อเป็นทางเลือกแทน android.util.Log มาตรฐาน แนวคิดหลักของ Timber คือการแทนที่ Log API แบบคงที่พร้อม tag ที่ต้องระบุด้วยตนเองด้วยกลไกอัตโนมัติที่กำหนดแหล่งที่มาของการเรียกผ่านสแต็ก

ไลบรารีสร้างขึ้นบนรูปแบบสถาปัตยกรรม Composite กับต้นไม้ (Tree) แทนที่จะเป็นคลาส Log เดียวที่มีพฤติกรรมคงที่ Timber จัดการ "ป่า" ของต้นไม้ — แต่ละต้นไม้รับผิดชอบช่องทางส่งออกของตนเอง: คอนโซล, ไฟล์, Crashlytics, เซิร์ฟเวอร์ระยะไกล นักพัฒนาสามารถเพิ่มต้นไม้จำนวนเท่าใดก็ได้และรวมเข้าด้วยกัน

ตาม Google I/O 2019 Google แนะนำ Timber เป็นแนวทางปฏิบัติที่ดีที่สุดสำหรับการบันทึกในแอปพลิเคชัน Android ไลบรารีใช้พื้นที่น้อยกว่า 10 KB ใน APK และไม่มี dependencies ภายนอก ทำให้เป็นตัวเลือกที่เหมาะสำหรับโปรเจกต์ทุกระดับ

Timber แก้ปัญหา tag ที่ไม่สอดคล้องกันในทีมขนาดใหญ่ เมื่อนักพัฒนาแต่ละคนเขียน tag ด้วยตนเอง ข้อผิดพลาดในการพิมพ์และความไม่สอดคล้องกันเป็นสิ่งที่หลีกเลี่ยงไม่ได้ — คลาสหนึ่งถูกบันทึกเป็น "MainActivity" อีกคลาสเป็น "MAIN_ACTIVITY" Timber จะดึง tag จากชื่อคลาสโดยอัตโนมัติ: MainActivity.kt → tag MainActivity

สถาปัตยกรรม Timber: ต้นไม้และป่า

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

DebugTree — การใช้งานในตัวสำหรับการพัฒนา

DebugTree คือการใช้งาน Tree มาตรฐานที่มาพร้อมกับไลบรารี มันกำหนด tag โดยการวิเคราะห์สแต็กการเรียก: มันขึ้นไป 8 เฟรมจากจุดเรียก Timber.d() และค้นหาชื่อคลาสที่เรียกใช้เมธอดบันทึก DebugTree จะปิดใช้งานโดยอัตโนมัติ (ไม่ส่งออกอะไร) ในบิลด์ release เพราะมันตรวจสอบ BuildConfig.DEBUG

วิธีการทำงานของป่า

Forest (ป่า) — การรวบรวมต้นไม้ที่ปลูกทั้งหมด เมื่อเรียกใช้เมธอด Timber.d("ข้อความ") ไลบรารีจะส่งข้อความไปยังต้นไม้ทั้งหมดตามลำดับที่ปลูก แต่ละต้นไม้สามารถกรองข้อความตามระดับ tag หรือเนื้อหา และประมวลผลในแบบของตนเอง

ลำดับการปลูกมีความสำคัญ: ต้นไม้ที่ปลูกก่อนจะถูกประมวลผลก่อน ขอแนะนำให้ปลูก DebugTree เป็นลำดับสุดท้าย เพื่อให้ต้นไม้แบบกำหนดเอง (เช่น Crashlytics) ประมวลผลข้อความก่อนที่จะถึง Logcat

ความปลอดภัยของเธรด

Timber เป็นเธรดที่ปลอดภัย — เมธอดทั้งหมดถูกซิงโครไนซ์ผ่านล็อกภายใน สิ่งนี้รับประกันว่าข้อความจากเธรดที่แตกต่างกันจะไม่ปะปนกัน อย่างไรก็ตามภายในต้นไม้แบบกำหนดเอง การซิงโครไนซ์เป็นความรับผิดชอบของนักพัฒนา: หากต้นไม้เขียนไปยังไฟล์ ต้องใช้ synchronized หรือ ReentrantLock

kotlin
// การเริ่มต้นป่าต้นไม้ใน Application.onCreate
class App : Application() {
    override fun onCreate() {
        super.onCreate()

        if (BuildConfig.DEBUG) {
            Timber.plant(Timber.DebugTree())
        }

        Timber.plant(CrashReportingTree())
        Timber.plant(FileLoggingTree())

        Timber.i("Timber planted with 3 trees")
    }
}

การติดตั้งและตั้งค่า Timber ในโปรเจกต์ Android

การติดตั้ง Timber ทำได้โดยเพิ่ม dependency เดียวใน build.gradle ไลบรารีเผยแพร่บน Maven Central ภายใต้ artifact com.jakewharton.timber:timber เวอร์ชันปัจจุบัน ณ ปี 2024 คือ 5.0.1 ซึ่งเป็นการอัปเดตเสถียรล่าสุด

groovy
// build.gradle (Module: app)
dependencies {
    implementation 'com.jakewharton.timber:timber:5.0.1'
}

การตั้งค่าขั้นต่ำ หลังการติดตั้ง — ปลูก DebugTree ใน Application.onCreate หากไม่มีขั้นตอนนี้ Timber จะละเว้นการเรียกบันทึกทั้งหมดโดยไม่โยนข้อยกเว้น นี่เป็นพฤติกรรมเริ่มต้นที่ปลอดภัย: หากไม่มีต้นไม้ถูกปลูก ไลบรารีจะทำงานว่างเปล่าโดยมีโอเวอร์เฮดน้อยที่สุด

ตาม Jake Wharton, 2023 70% ของปัญหา Timber สำหรับผู้ใช้ใหม่เกี่ยวข้องกับการเริ่มต้นที่ลืมหรือไม่ถูกต้อง Timber ไม่สร้างข้อผิดพลาดเมื่อไม่มีต้นไม้ — นักพัฒนาคาดหวังให้บันทึกปรากฏใน Logcat แต่ไม่มีอะไรเกิดขึ้น

สำหรับการทดสอบ Timber มี Timber.asTree() — เมธอดที่ส่งคืนต้นไม้ปัจจุบันหรือ null สะดวกสำหรับการทดสอบหน่วย: คุณสามารถแทนที่ต้นไม้ด้วย mock และยืนยันว่าข้อความบันทึกถูกส่งด้วยระดับและ tag ที่ถูกต้อง

การสร้าง Tree แบบกำหนดเองสำหรับการจัดการบันทึกที่กำหนดเอง

ต้นไม้แบบกำหนดเอง — เหตุผลหลักในการใช้ Timber แทน Log API มาตรฐาน โดยการแทนที่เมธอดของ Tree คุณสามารถกำหนดเส้นทางบันทึกทุกระดับไปยัง Crashlytics, ระบบไฟล์, Remote Config หรือเซิร์ฟเวอร์ของคุณเอง

kotlin
class CrashReportingTree : Timber.Tree() {

    override fun isLoggable(tag: String?, priority: Int): Boolean {
        // เฉพาะ Error และ WTF สำหรับการรายงานข้อขัดข้อง
        return priority >= Log.ERROR
    }

    override fun log(priority: Int, tag: String?,
                   message: String, t: Throwable?) {
        if (t != null) {
            FirebaseCrashlytics.getInstance()
                .recordException(t)
        } else {
            FirebaseCrashlytics.getInstance()
                .log("[$tag] $message")
        }
    }
}

เมธอดที่ต้องแทนที่: isLoggable(tag, priority) — ตัวกรองที่กำหนดว่าจะประมวลผลข้อความหรือไม่ (การใช้งานพื้นฐานส่งคืน true) log(priority, tag, message, t) — ตรรกะการประมวลผลหลัก prepareLog(priority, tag, throwable, message, args) — เรียกก่อนการจัดรูปแบบ อนุญาตให้แก้ไขข้อความก่อนการประมวลผล

ข้อได้เปรียบที่สำคัญของต้นไม้แบบกำหนดเองคือ ไม่มีรีเฟลกชัน แตกต่างจากเฟรมเวิร์กการบันทึกหลายตัว Timber ไม่ใช้ Reflection API เพื่อกำหนด tag หรือระดับ Tag ถูกคำนวณผ่านการวิเคราะห์สแต็กการเรียก (Throwable.stackTrace) ซึ่งทำงานเร็วกว่าหลายเท่า

Timber เทียบกับ android.util.Log มาตรฐาน

การเปรียบเทียบ Timber และ Log API มาตรฐานแสดงให้เห็นความแตกต่างหลักสี่ประการ: tag อัตโนมัติ, รองรับการจัดรูปแบบสตริงด้วย varargs, ช่องทางส่งออกหลายช่อง และพฤติกรรมที่ปลอดภัยเมื่อไม่ได้เริ่มต้น

พารามิเตอร์android.util.LogTimber
การตรวจจับ tagด้วยตนเอง, ค่าคงที่สตริงอัตโนมัติ, ผ่านสแต็กการเรียก
การจัดรูปแบบการต่อสตริงหรือ String.formatvarargs ในตัว + ตัวยึดตำแหน่ง %s
ช่องทางส่งออกLogcat เท่านั้นต้นไม้: Logcat, ไฟล์, Crashlytics ฯลฯ
พฤติกรรมเมื่อไม่ได้เริ่มต้นทำงานเสมอไม่ส่งออกอะไร
ประสิทธิภาพระดับพื้นฐานการจัดรูปแบบแบบขี้เกียจผ่าน isLoggable

ข้อโต้แย้งหลักต่อ Timber — การพึ่งพาไลบรารีของบุคคลที่สาม สำหรับโปรเจกต์ธรรมดาที่มีการบันทึกน้อยที่สุด การใช้ Timber อาจมากเกินไป อย่างไรก็ตาม ตาม Google Play Console, 2024 มากกว่า 60% ของ 1,000 แอปอันดับต้น ๆ ใน Google Play ใช้ Timber ซึ่งยืนยันความน่าเชื่อถือและประสิทธิภาพ

ประสิทธิภาพของ Timber ในบิลด์ release เทียบเท่ากับ Log API มาตรฐาน เมื่อไม่มีต้นไม้ถูกปลูก เมธอด Timber.d() จะตรวจสอบการมีอยู่ของต้นไม้ (if เดียว) และส่งคืน — โดยไม่จัดรูปแบบสตริง ซึ่งเร็วกว่า Log.d() ที่มีการต่อสตริงซึ่งทำงานเสมอ

แนวทางปฏิบัติที่ดีที่สุดเมื่อใช้ Timber

กฎข้อแรก — ตรวจสอบการเริ่มต้น Timber ในทดสอบเสมอ ใช้ Timber.asTree() เพื่อยืนยันว่าต้นไม้ถูกปลูก ในการทดสอบหน่วย ให้ปลูก TestTree ซึ่งบันทึกข้อความในรายการสำหรับการตรวจสอบ assert

กฎข้อที่สอง — อย่าผสม Timber และ android.util.Log ในโปรเจกต์เดียวกัน หากโปรเจกต์ใช้ Timber อยู่แล้ว การเรียกบันทึกใหม่ทั้งหมดควรผ่านมัน การผสมทำให้เกิดข้อความซ้ำและความสับสนในการวิเคราะห์

กฎข้อที่สาม — ปลูก CrashReportingTree โดยไม่ตรวจสอบ BuildConfig.DEBUG ซึ่งแตกต่างจาก DebugTree ต้นไม้ขัดข้องควรทำงานทั้งใน debug และ release — สิ่งนี้ช่วยให้แน่ใจว่าข้อผิดพลาดในการทดสอบจะถูกจับโดยระบบรายงานขัดข้อง

กฎข้อที่สี่ — ใช้ระดับ Timber ในตัว: Timber.v(), Timber.d(), Timber.i(), Timber.w(), Timber.e(), Timber.wtf() หลีกเลี่ยงการเรียก Timber.log() โดยตรงด้วยลำดับความสำคัญที่เป็นตัวเลข — สิ่งนี้ลดความสามารถในการอ่านโค้ดและทำให้การปรับโครงสร้างซับซ้อน

กฎข้อที่ห้า — สำหรับไลบรารีและโมดูล ให้ใช้ Timber.tag("CustomTag") เมธอดนี้ส่งคืนต้นไม้ชั่วคราวที่มี tag ถูกแทนที่โดยไม่ส่งผลต่อการกำหนดค่าส่วนกลาง สิ่งนี้ช่วยให้บันทึกจากโค้ดไลบรารีด้วยตัวระบุที่กำหนดเอง

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

สามารถใช้ Timber ในโมดูลไลบรารี Android ได้หรือไม่?

ได้ — Timber ปลอดภัยที่จะใช้ในไลบรารี หากไม่มีต้นไม้ถูกปลูกในแอปพลิเคชัน การเรียก Timber จะไม่ทำให้เกิดข้อผิดพลาด สำหรับไลบรารี ขอแนะนำให้ใช้ Timber.tag("LibraryTag") เพื่อระบุแหล่งที่มาของบันทึก

Timber กำหนด tag โดยไม่ต้องระบุด้วยตนเองอย่างไร?

ผ่านสแต็กการเรียก (stack trace) — DebugTree ขึ้นไป 8 เฟรมจากจุดเรียก Timber.d() และดึงชื่อคลาส เมธอด Throwable.stackTrace ใช้เพื่อกำหนดคลาสที่เรียกโดยไม่มีโอเวอร์เฮดของ Reflection API

Timber แตกต่างจาก Logcat อย่างไร?

Logcat เป็นยูทิลิตี้ระบบ Android สำหรับดูบันทึก Timber เป็นไลบรารีสำหรับเขียนบันทึก Timber ส่งข้อความไปยัง Logcat ผ่าน DebugTree แต่ยังสามารถส่งไปยังไฟล์ Crashlytics Sentry และช่องทางอื่น ๆ ผ่านต้นไม้แบบกำหนดเอง

Timber รองรับ Kotlin Multiplatform หรือไม่?

ไม่ — Timber ผูกพันกับ Android SDK (android.util.Log) สำหรับโปรเจกต์ KMP ให้พิจารณา Kermit หรือ Napier — ไลบรารีการบันทึกข้ามแพลตฟอร์มที่มีสถาปัตยกรรมต้นไม้คล้ายกัน ทำงานบน Android, iOS, JVM และ JS

วิธีลบต้นไม้ที่ปลูกทั้งหมดใน Timber?

ใช้ Timber.uprootAll() — เมธอดลบต้นไม้ที่ลงทะเบียนทั้งหมด Timber.uproot(tree) ลบต้นไม้เฉพาะ สิ่งนี้มีประโยชน์ในการทดสอบสำหรับการรีเซ็ตสถานะระหว่างเมธอดทดสอบ

สรุป

  • Timber — ตัวหุ้มน้ำหนักเบาบน android.util.Log พร้อม tag อัตโนมัติและสถาปัตยกรรมต้นไม้
  • Tree — องค์ประกอบพื้นฐาน แต่ละต้นไม้กำหนดช่องทางส่งออกบันทึกของตนเอง
  • DebugTree — การใช้งานในตัวสำหรับ Logcat ปิดใช้งานอัตโนมัติใน release
  • Custom Tree — ส่งบันทึกไปยัง Crashlytics, ไฟล์, เซิร์ฟเวอร์หรือช่องทางอื่น ๆ
  • Timber.tag() — การเปลี่ยน tag ชั่วคราวสำหรับโค้ดไลบรารีโดยไม่ต้องกำหนดค่าส่วนกลาง
  • ความปลอดภัยของเธรด — เมธอด Timber ทั้งหมดถูกซิงโครไนซ์ ต้นไม้แบบกำหนดเองต้องการการซิงโครไนซ์ของตัวเอง
  • ความเงียบที่ปลอดภัย — เมื่อไม่มีต้นไม้ Timber ไม่โยนข้อยกเว้นและไม่ใช้ทรัพยากร

เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร

IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ

ปรึกษาโครงการ

อ่านเพิ่มเติม