Timber — apa itu, API perpustakaan dan contoh penggunaan

Penulis: IT Sectr Diterbitkan: 2026-05-28 Waktu membaca: 8 mnt

Timber — perpustakaan logging ringan untuk Android dengan arsitektur yang dapat diperluas berdasarkan pohon (Tree), yang telah menggantikan android.util.Log standar dalam ribuan proyek. Menurut data GitHub, 2024, perpustakaan ini telah mengumpulkan lebih dari 10.000 bintang dan digunakan dalam aplikasi dengan audiens lebih dari 1 miliar instalasi. Timber memecahkan tiga masalah utama Log API: tidak adanya tag otomatis, pemeriksaan isLoggable wajib, dan sifat statis dari panggilan.

Poin Utama

  • Timber — pembungkus di atas android.util.Log dengan penentuan tag otomatis berdasarkan nama kelas dan stack panggilan
  • Tree — elemen dasar arsitektur Timber, setiap instance menentukan cara memproses pesan log
  • Menanam pohon (Planting) — proses pendaftaran Tree di Timber, biasanya dilakukan sekali di Application.onCreate
  • DebugTree — implementasi bawaan untuk build Debug, mengeluarkan log ke Logcat dengan tag dari nama kelas
  • Custom Tree — kemampuan untuk membuat implementasi sendiri untuk mengirim log ke Crashlytics, file, atau server

Apa itu Timber

Timber — adalah perpustakaan open-source untuk Android, dibuat oleh Jake Wharton pada tahun 2013 sebagai alternatif untuk android.util.Log standar. Ide kunci Timber — mengganti Log API statis dengan tag manual wajib dengan mekanisme otomatis yang menentukan sumber panggilan melalui stack.

Perpustakaan ini dibangun di atas pola arsitektur Composite dengan pohon (Tree). Alih-alih satu kelas Log dengan perilaku tetap, Timber mengelola “hutan” pohon — setiap pohon bertanggung jawab atas saluran keluarannya sendiri: konsol, file, Crashlytics, server jarak jauh. Pengembang dapat menambahkan sejumlah pohon dan menggabungkannya.

Menurut data Google I/O 2019, Timber direkomendasikan oleh Google sebagai praktik terbaik untuk logging di aplikasi Android. Perpustakaan ini memakan kurang dari 10 KB di APK dan tidak memiliki ketergantungan eksternal, menjadikannya pilihan ideal untuk proyek berbagai ukuran.

Timber memecahkan masalah tag yang tidak konsisten di tim besar. Ketika setiap pengembang menulis tag secara manual, kesalahan ketik dan perbedaan tidak terhindarkan — satu kelas log sebagai “MainActivity”, yang lain sebagai “MAIN_ACTIVITY”. Timber secara otomatis mengekstrak tag dari nama kelas:MainActivity.kt → tag MainActivity.

Arsitektur Timber: pohon dan hutan

Arsitektur Timber terdiri dari dua komponen: kelas statis pusat Timber dan kelas abstrak Timber.Tree. Timber bertindak sebagai fasad yang mendelegasikan setiap panggilan log ke semua pohon yang ditanam (planted). Setiap pohon memutuskan apakah perlu memproses pesan, dan jika ya — ke mana harus mengarahkannya.

DebugTree — implementasi bawaan untuk pengembangan

DebugTree — implementasi Tree standar yang disertakan dengan perpustakaan. Ini menentukan tag melalui analisis stack panggilan: naik 8 frame dari titik panggilan Timber.d() dan menemukan nama kelas yang memanggil metode log. DebugTree secara otomatis dinonaktifkan (tidak mengeluarkan apa pun) di build release karena memeriksa BuildConfig.DEBUG.

Prinsip kerja “hutan”

Forest (hutan) — kumpulan semua pohon yang ditanam. Ketika metode Timber.d(“pesan”) dipanggil, perpustakaan secara iteratif mengirimkan pesan ke semua pohon dalam urutan penanaman. Setiap pohon dapat memfilter pesan berdasarkan level, tag, atau konten dan memprosesnya dengan caranya sendiri.

Urutan penanaman itu penting: pohon yang ditanam pertama diproses pertama. Disarankan untuk menanam DebugTree sebagai yang terakhir, sehingga pohon kustom (misalnya Crashlytics) memproses pesan sebelum masuk ke Logcat.

Keamanan thread

Timber aman untuk thread — semua metode disinkronkan melalui kunci internal. Ini menjamin bahwa pesan dari thread yang berbeda tidak tercampur. Namun, di dalam pohon kustom, sinkronisasi menjadi tanggung jawab pengembang: jika pohon menulis ke file, harus menggunakan synchronized atau ReentrantLock.

kotlin
// Inisialisasi hutan pohon di 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")
    }
}

Instalasi dan konfigurasi Timber di proyek Android

Instalasi Timber dilakukan dengan menambahkan satu ketergantungan di build.gradle. Perpustakaan ini dipublikasikan di Maven Central dengan artifact com.jakewharton.timber:timber. Versi saat ini untuk 2024 — 5.0.1, pembaruan stabil terakhir.

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

Konfigurasi minimal setelah instalasi — menanam DebugTree di Application.onCreate. Tanpa langkah ini, Timber akan mengabaikan semua panggilan log, tanpa melempar pengecualian. Ini adalah perilaku default yang aman: jika pohon tidak ditanam, perpustakaan berjalan kosong dengan overhead minimal.

Menurut data Jake Wharton, 2023, 70% masalah dengan Timber pada pengguna baru terkait dengan inisialisasi yang terlupa atau salah. Timber tidak menghasilkan kesalahan saat tidak ada pohon — pengembang mengharapkan log muncul di Logcat, tetapi tidak terjadi apa-apa.

Untuk pengujian, Timber menyediakan Timber.asTree() — metode yang mengembalikan pohon saat ini atau null. Ini berguna untuk pemeriksaan di unit test: pohon dapat diganti dengan mock dan memeriksa apakah pesan log telah dikirim dengan level dan tag yang benar.

Membuat Tree sendiri untuk pemrosesan log kustom

Pohon kustom — alasan utama menggunakan Timber alih-alih Log API standar. Dengan menimpa metode Tree, log dari level apa pun dapat diarahkan ke Crashlytics, sistem file, Remote Config, atau server sendiri.

kotlin
class CrashReportingTree : Timber.Tree() {

    override fun isLoggable(tag: String?, priority: Int): Boolean {
        // Hanya Error dan WTF untuk crash-reporting
        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")
        }
    }
}

Metode yang dapat ditimpa: isLoggable(tag, priority) — filter yang menentukan apakah pesan perlu diproses (implementasi dasar mengembalikan true). log(priority, tag, message, t) — logika pemrosesan utama. prepareLog(priority, tag, throwable, message, args) — dipanggil sebelum pemformatan, memungkinkan mengubah pesan sebelum diproses.

Keuntungan penting dari pohon kustom — tidak ada refleksi. Tidak seperti banyak framework logging, Timber tidak menggunakan Reflection API untuk menentukan tag atau level. Tag dihitung melalui analisis stack panggilan (Throwable.stackTrace), yang bekerja jauh lebih cepat.

Timber vs android.util.Log standar

Perbandingan Timber dengan Log API standar menunjukkan empat perbedaan utama: tag otomatis, dukungan pemformatan string dengan varargs, kemungkinan beberapa saluran keluaran, dan perilaku aman saat tidak ada inisialisasi.

Parameterandroid.util.LogTimber
Penentuan tagManual, konstanta stringOtomatis, berdasarkan stack panggilan
PemformatanKonkatenasi atau String.formatVarargs bawaan + placeholder %s
Saluran keluaranHanya LogcatPohon: Logcat, file, Crashlytics, dll.
Perilaku tanpa inisialisasiSelalu berfungsiTidak mengeluarkan apa pun
KinerjaTingkat dasarPemformatan malas melalui isLoggable

Argumen utama menentang Timber — ketergantungan pada perpustakaan pihak ketiga. Untuk proyek sederhana dengan logging minimal, penggunaan Timber mungkin berlebihan. Namun, menurut data Google Play Console, 2024, lebih dari 60% dari top-1000 aplikasi di Google Play menggunakan Timber, yang menegaskan keandalan dan efektivitasnya.

Kinerja Timber di build release tidak kalah dengan Log API standar. Saat tidak ada pohon yang ditanam, metode Timber.d() memeriksa keberadaan pohon (satu if) dan kembali — tanpa pemformatan string. Ini lebih cepat daripada Log.d() dengan konkatenasi yang selalu dijalankan.

Best practices saat menggunakan Timber

Aturan pertama — selalu periksa inisialisasi Timber dalam tes. Gunakan Timber.asTree() untuk memverifikasi bahwa pohon telah ditanam. Dalam unit test, tanam TestTree yang menyimpan pesan dalam daftar untuk pemeriksaan assert.

Aturan kedua — jangan campur Timber dan android.util.Log dalam satu proyek. Jika proyek sudah menggunakan Timber, semua panggilan log baru harus melaluinya. Mencampur menyebabkan duplikasi pesan dan kebingungan saat analisis.

Aturan ketiga — tanam CrashReportingTree tanpa pemeriksaan BuildConfig.DEBUG. Tidak seperti DebugTree, pohon crash harus bekerja baik di debug maupun release — ini memastikan bahwa kesalahan pengujian juga masuk ke sistem crash-reporting.

Aturan keempat — gunakan level bawaan Timber: Timber.v(), Timber.d(), Timber.i(), Timber.w(), Timber.e(), Timber.wtf(). Hindari panggilan langsung Timber.log() dengan priority numerik — ini mengurangi keterbacaan kode dan mempersulit refactoring.

Aturan kelima — untuk perpustakaan dan modul, gunakan Timber.tag(“CustomTag”). Metode ini mengembalikan pohon sementara dengan tag yang ditimpa, tanpa memengaruhi konfigurasi global. Ini memungkinkan logging dari kode perpustakaan dengan pengidentifikasi kustom.

Pertanyaan yang Sering Diajukan

Bisakah Timber digunakan di modul perpustakaan Android?

Ya — Timber aman digunakan di perpustakaan. Jika pohon tidak ditanam di aplikasi, panggilan Timber tidak menyebabkan kesalahan. Untuk perpustakaan, disarankan menggunakan Timber.tag(“LibraryTag”) untuk mengidentifikasi sumber log.

Bagaimana cara Timber menentukan tag tanpa penunjukan manual?

Melalui stack panggilan (stack trace) — DebugTree naik 8 frame dari titik panggilan Timber.d() dan mengekstrak nama kelas. Metode Throwable.stackTrace digunakan untuk menentukan kelas pemanggil tanpa biaya Reflection API.

Apa perbedaan Timber dengan Logcat?

Logcat — utilitas sistem Android untuk melihat log. Timber — perpustakaan untuk menulis log. Timber mengeluarkan pesan ke Logcat melalui DebugTree, tetapi juga dapat mengirimkannya ke file, Crashlytics, Sentry, dan saluran lain melalui pohon kustom.

Apakah Timber mendukung Kotlin Multiplatform?

Tidak — Timber terikat pada Android SDK (android.util.Log). Untuk proyek KMP, pertimbangkan Kermit atau Napier — perpustakaan logging multiplatform dengan arsitektur pohon serupa yang berfungsi di Android, iOS, JVM, dan JS.

Bagaimana cara menghapus semua pohon yang ditanam di Timber?

Gunakan Timber.uprootAll() — metode ini menghapus semua pohon yang terdaftar. Timber.uproot(tree) menghapus pohon tertentu. Ini berguna dalam tes untuk mereset status antar metode pengujian.

Kesimpulan

  • Timber — pembungkus ringan di atas android.util.Log dengan tag otomatis dan arsitektur pohon
  • Tree — elemen dasar, setiap pohon menentukan saluran keluaran lognya sendiri
  • DebugTree — implementasi bawaan untuk Logcat, secara otomatis dinonaktifkan di release
  • Custom Tree — mengirim log ke Crashlytics, file, server, atau saluran lainnya
  • Timber.tag() — perubahan tag sementara untuk kode perpustakaan tanpa konfigurasi global
  • Keamanan thread — semua metode Timber disinkronkan, pohon kustom memerlukan sinkronisasi sendiri
  • Diam yang aman — saat tidak ada pohon, Timber tidak melempar pengecualian dan tidak mengonsumsi sumber daya

Kami akan mengembangkan aplikasi seluler turnkey

IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.

Diskusikan proyek

Baca juga