Timber — ano ito, API ng library at mga halimbawa ng paggamit

May-akda: IT Sectr Nai-publish: 2026-05-28 Oras ng pagbabasa: 8 min

Timber — isang magaan na library ng pag-log para sa Android na may napapalawak na arkitektura batay sa mga puno (Tree), na pumalit sa karaniwang android.util.Log sa libu-libong proyekto. Ayon sa datos ng GitHub, 2024, ang library ay nakaipon ng mahigit 10,000 bituin at ginagamit sa mga app na may audience na mahigit 1 bilyong pag-install. Nilulutas ng Timber ang tatlong pangunahing problema ng Log API: kawalan ng awtomatikong tag, mandatoryong pagsusuri ng isLoggable at static na kalikasan ng mga tawag.

Mga Pangunahing Punto

  • Timber — isang wrapper sa ibabaw ng android.util.Log na may awtomatikong pagtukoy ng tag batay sa pangalan ng klase at stack ng tawag
  • Tree — pangunahing elemento ng arkitektura ng Timber, bawat instance ay tumutukoy kung paano iproseso ang log message
  • Pagtatanim ng mga puno (Planting) — proseso ng pagrerehistro ng Tree sa Timber, karaniwang ginagawa nang isang beses sa Application.onCreate
  • DebugTree — built-in na implementasyon para sa Debug builds, naglalabas ng log sa Logcat na may tag mula sa pangalan ng klase
  • Custom Tree — kakayahang lumikha ng sariling implementasyon para magpadala ng log sa Crashlytics, file, o server

Ano ang Timber

Timber — ay isang open-source library para sa Android, na ginawa ni Jake Wharton noong 2013 bilang alternatibo sa karaniwang android.util.Log. Ang pangunahing ideya ng Timber — palitan ang static na Log API na may mandatoryong manual tag ng isang awtomatikong mekanismo na tumutukoy sa pinagmulan ng tawag sa pamamagitan ng stack.

Ang library ay binuo sa pattern ng arkitektura na Composite na may mga puno (Tree). Sa halip na isang solong Log class na may nakapirming pag-uugali, pinamamahalaan ng Timber ang isang “kagubatan” ng mga puno — bawat puno ay responsable para sa sarili nitong channel ng output: console, file, Crashlytics, malayuang server. Maaaring magdagdag ang developer ng anumang bilang ng mga puno at pagsamahin ang mga ito.

Ayon sa datos ng Google I/O 2019, inirerekomenda ng Google ang Timber bilang pinakamahusay na kasanayan para sa pag-log sa mga Android app. Ang library ay sumasakop ng mas mababa sa 10 KB sa APK at walang panlabas na dependencies, ginagawa itong perpektong pagpipilian para sa mga proyekto ng anumang laki.

Nilulutas ng Timber ang problema ng hindi pare-parehong mga tag sa malalaking koponan. Kapag ang bawat developer ay sumulat ng tag nang manu-mano, ang mga typo at pagkakaiba ay hindi maiiwasan — isang klase ay nagla-log bilang “MainActivity”, isa pa bilang “MAIN_ACTIVITY”. Awtomatikong kinukuha ng Timber ang tag mula sa pangalan ng klase:MainActivity.kt → tag MainActivity.

Arkitektura ng Timber: mga puno at kagubatan

Ang arkitektura ng Timber ay binubuo ng dalawang bahagi: ang sentral na static na klase na Timber at ang abstract na klase na Timber.Tree. Ang Timber ay gumaganap bilang isang facade na nagtatalaga ng bawat log call sa lahat ng nakatanim na (planted) puno. Bawat puno ay nagpapasya kung kailangan nitong iproseso ang mensahe, at kung oo — saan ito ididirekta.

DebugTree — built-in na implementasyon para sa pag-develop

DebugTree — ang karaniwang implementasyon ng Tree na kasama ng library. Tinutukoy nito ang tag sa pamamagitan ng pagsusuri ng call stack: tumaas ng 8 frame mula sa punto ng tawag ng Timber.d() at hinahanap ang pangalan ng klase na tumawag sa log method. Awtomatikong nadi-disable ang DebugTree (walang inilalabas) sa release builds dahil sinusuri nito ang BuildConfig.DEBUG.

Prinsipyo ng pagpapatakbo ng “kagubatan”

Forest (kagubatan) — ang koleksyon ng lahat ng nakatanim na puno. Kapag tinawag ang pamamaraang Timber.d(“mensahe”), ang library ay paulit-ulit na nagpapadala ng mensahe sa lahat ng puno sa pagkakasunud-sunod ng pagtatanim. Bawat puno ay maaaring mag-filter ng mensahe ayon sa antas, tag, o nilalaman at iproseso ito sa sarili nitong paraan.

Mahalaga ang pagkakasunud-sunod ng pagtatanim: ang unang nakatanim na puno ay unang pinoproseso. Inirerekomenda na itanim ang DebugTree bilang huli, upang ang mga kustom na puno (hal. Crashlytics) ay maproseso ang mensahe bago ito makarating sa Logcat.

Kaligtasan ng thread

Ang Timber ay ligtas para sa thread — lahat ng pamamaraan ay naka-synchronize sa pamamagitan ng internal lock. Ginagarantiyahan nito na ang mga mensahe mula sa iba't ibang thread ay hindi maghahalo. Gayunpaman, sa loob ng isang kustom na puno, ang synchronization ay nasa responsibilidad ng developer: kung ang puno ay sumusulat sa isang file, dapat gamitin ang synchronized o ReentrantLock.

kotlin
// Pagsisimula ng kagubatan ng mga puno sa 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")
    }
}

Pag-install at pagsasaayos ng Timber sa proyektong Android

Pag-install ng Timber ay ginagawa sa pamamagitan ng pagdaragdag ng isang dependency sa build.gradle. Ang library ay nai-publish sa Maven Central sa ilalim ng artifact na com.jakewharton.timber:timber. Kasalukuyang bersyon para sa 2024 — 5.0.1, huling stable na update.

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

Pinakamababang pagsasaayos pagkatapos ng pag-install — pagtatanim ng DebugTree sa Application.onCreate. Kung wala ang hakbang na ito, babalewalain ng Timber ang lahat ng log call, nang hindi nagtatapon ng exceptions. Ito ay isang ligtas na default na pag-uugali: kung ang puno ay hindi nakatanim, ang library ay tumatakbo nang walang ginagawa na may minimal na overhead.

Ayon sa datos ng Jake Wharton, 2023, 70% ng mga problema sa Timber sa mga bagong user ay may kaugnayan sa nakalimutan o maling pagsisimula. Hindi nagkakamali ang Timber kapag walang puno — inaasahan ng mga developer na lalabas ang log sa Logcat, ngunit walang nangyayari.

Para sa pagsubok, nagbibigay ang Timber ng Timber.asTree() — isang pamamaraan na nagbabalik ng kasalukuyang puno o null. Ito ay maginhawa para sa pagsusuri sa unit test: maaaring palitan ang puno ng mock at suriin kung ang log message ay naipadala na may tamang antas at tag.

Paggawa ng sariling Tree para sa kustomisadong pagproseso ng log

Kustom na puno — ang pangunahing dahilan para gamitin ang Timber sa halip na karaniwang Log API. Sa pamamagitan ng pag-override ng mga pamamaraan ng Tree, maaaring idirekta ang log ng anumang antas sa Crashlytics, file system, Remote Config, o sariling server.

kotlin
class CrashReportingTree : Timber.Tree() {

    override fun isLoggable(tag: String?, priority: Int): Boolean {
        // Error at WTF lang para sa 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")
        }
    }
}

Mga pamamaraang maaaring i-override: isLoggable(tag, priority) — filter na tumutukoy kung kailangan iproseso ang mensahe (ang base implementasyon ay nagbabalik ng true). log(priority, tag, message, t) — pangunahing lohika ng pagproseso. prepareLog(priority, tag, throwable, message, args) — tinatawag bago ang pag-format, pinapayagan baguhin ang mensahe bago ito iproseso.

Isang mahalagang bentahe ng kustom na mga puno — kawalan ng reflection. Hindi tulad ng maraming logging framework, hindi ginagamit ng Timber ang Reflection API para matukoy ang tag o antas. Ang tag ay kinakalkula sa pamamagitan ng pagsusuri ng call stack (Throwable.stackTrace), na gumagana nang mas mabilis.

Timber vs karaniwang android.util.Log

Paghahambing ng Timber sa karaniwang Log API ay nagpapakita ng apat na pangunahing pagkakaiba: awtomatikong tag, suporta para sa pag-format ng string na may varargs, posibilidad ng maramihang output channel, at ligtas na pag-uugali kapag walang pagsisimula.

Parameterandroid.util.LogTimber
Pagtukoy ng tagManual, string constantAwtomatiko, batay sa call stack
Pag-formatConcatenation o String.formatBuilt-in na varargs + placeholder %s
Output channelLogcat langMga puno: Logcat, file, Crashlytics atbp.
Pag-uugali nang walang pagsisimulaLaging gumaganaWalang inilalabas
PagganapBatayang antasMabagal na pag-format sa pamamagitan ng isLoggable

Pangunahing argumento laban sa Timber — dependency sa isang third-party na library. Para sa isang simpleng proyekto na may minimal na pag-log, ang paggamit ng Timber ay maaaring sobra. Gayunpaman, ayon sa datos ng Google Play Console, 2024, mahigit 60% ng top-1000 na app sa Google Play ang gumagamit ng Timber, na nagpapatunay ng pagiging maaasahan at kahusayan nito.

Ang pagganap ng Timber sa release builds ay hindi mababa sa karaniwang Log API. Kapag walang nakatanim na puno, ang pamamaraang Timber.d() ay sumusuri sa presensya ng mga puno (isang if) at bumabalik — nang walang pag-format ng string. Ito ay mas mabilis kaysa sa Log.d() na may concatenation na palaging isinasagawa.

Best practices sa paggamit ng Timber

Unang panuntunan — palaging suriin ang pagsisimula ng Timber sa mga test. Gamitin ang Timber.asTree() upang patunayan na ang puno ay nakatanim. Sa unit test, magtanim ng TestTree na nag-iimbak ng mga mensahe sa isang listahan para sa assert checks.

Ikalawang panuntunan — huwag paghaluin ang Timber at android.util.Log sa iisang proyekto. Kung ang proyekto ay gumagamit na ng Timber, lahat ng bagong log call ay dapat dumaan dito. Ang paghahalo ay humahantong sa pagdoble ng mga mensahe at kalituhan sa pagsusuri.

Ikatlong panuntunan — itanim ang CrashReportingTree nang walang pagsusuri ng BuildConfig.DEBUG. Hindi tulad ng DebugTree, ang crash tree ay dapat gumana pareho sa debug at release — ginagarantiyahan nito na ang mga error sa pagsubok ay mapupunta rin sa crash-reporting system.

Ikaapat na panuntunan — gamitin ang built-in na antas ng Timber: Timber.v(), Timber.d(), Timber.i(), Timber.w(), Timber.e(), Timber.wtf(). Iwasan ang direktang pagtawag sa Timber.log() na may numerikong priority — nababawasan nito ang pagiging madaling mabasa ng code at nagpapahirap sa refactoring.

Ikalimang panuntunan — para sa mga library at module, gamitin ang Timber.tag(“CustomTag”). Ang pamamaraang ito ay nagbabalik ng pansamantalang puno na may override na tag, nang hindi naaapektuhan ang global configuration. Pinapayagan nito ang pag-log mula sa library code na may kustom na identifier.

Mga Madalas Itanong

Maaari bang gamitin ang Timber sa isang library module ng Android?

Oo — ang Timber ay ligtas gamitin sa mga library. Kung ang puno ay hindi nakatanim sa app, ang mga tawag sa Timber ay hindi nagdudulot ng mga error. Para sa mga library, inirerekomenda ang paggamit ng Timber.tag(“LibraryTag”) para sa pagtukoy ng pinagmulan ng log.

Paano tinutukoy ng Timber ang tag nang walang manu-manong pagtukoy?

Sa pamamagitan ng call stack (stack trace) — ang DebugTree ay tumataas ng 8 frame mula sa punto ng tawag ng Timber.d() at kinukuha ang pangalan ng klase. Ang pamamaraang Throwable.stackTrace ay ginagamit upang matukoy ang tumatawag na klase nang walang gastos ng Reflection API.

Paano naiiba ang Timber sa Logcat?

Logcat — system utility ng Android para sa pagtingin ng mga log. Timber — library para sa pagsulat ng mga log. Ang Timber ay naglalabas ng mga mensahe sa Logcat sa pamamagitan ng DebugTree, ngunit maaari rin itong magpadala sa kanila sa mga file, Crashlytics, Sentry, at iba pang channel sa pamamagitan ng kustom na mga puno.

Sinusuportahan ba ng Timber ang Kotlin Multiplatform?

Hindi — ang Timber ay nakatali sa Android SDK (android.util.Log). Para sa KMP projects, isaalang-alang ang Kermit o Napier — mga multiplatform logging library na may katulad na arkitektura ng puno na gumagana sa Android, iOS, JVM, at JS.

Paano tanggalin ang lahat ng nakatanim na puno sa Timber?

Gamitin ang Timber.uprootAll() — ang pamamaraang ito ay nag-aalis ng lahat ng rehistradong puno. Timber.uproot(tree) ay nag-aalis ng isang partikular na puno. Ito ay kapaki-pakinabang sa mga test para i-reset ang estado sa pagitan ng mga pamamaraan ng pagsubok.

Buod

  • Timber — magaan na wrapper sa ibabaw ng android.util.Log na may awtomatikong tag at arkitektura ng puno
  • Tree — pangunahing elemento, bawat puno ay tumutukoy sa sarili nitong output channel ng log
  • DebugTree — built-in na implementasyon para sa Logcat, awtomatikong nadi-disable sa release
  • Custom Tree — nagpapadala ng log sa Crashlytics, mga file, server, o anumang iba pang channel
  • Timber.tag() — pansamantalang pagbabago ng tag para sa library code nang walang global configuration
  • Kaligtasan ng thread — lahat ng pamamaraan ng Timber ay naka-synchronize, ang kustom na mga puno ay nangangailangan ng sariling synchronization
  • Ligtas na katahimikan — kapag walang mga puno, ang Timber ay hindi nagtatapon ng exception at hindi kumukonsumo ng resources

Gagawa kami ng mobile application na turnkey

Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.

Pag-usapan ang proyekto

Basahin din