Timber — mi ez, a könyvtár API-ja és használati példák

Szerző: IT Sectr Megjelenés: 2026-05-28 Olvasási idő: 8 perc

Timber — egy könnyű naplózási könyvtár Androidhoz, kiterjeszthető, fákon (Tree) alapuló architektúrával, amely ezernyi projektben váltotta fel a szabványos android.util.Log-ot. A GitHub, 2024 adatai szerint a könyvtár több mint 10 000 csillagot gyűjtött, és több mint 1 milliárd telepítéssel rendelkező alkalmazásokban használják. A Timber a Log API három fő problémáját oldja meg: az automatikus tag hiányát, a kötelező isLoggable ellenőrzést és a hívások statikus természetét.

Főbb pontok

  • Timber — egy wrapper az android.util.Log körül, automatikus tag meghatározással osztálynév és hívási verem alapján
  • Tree — a Timber architektúra alapeleme, minden példány meghatározza, hogyan dolgozza fel a naplóüzenetet
  • Fák ültetése (Planting) — a Tree regisztrálásának folyamata a Timber-ben, általában egyszer történik az Application.onCreate-ben
  • DebugTree — beépített implementáció Debug-verziókhoz, az osztály nevéből származó tag-gal írja ki a naplókat a Logcat-be
  • Custom Tree — lehetőség saját implementáció létrehozására naplók Crashlytics-be, fájlba vagy szerverre küldéséhez

Mi az a Timber

Timber — egy nyílt forráskódú könyvtár Androidhoz, amelyet Jake Wharton hozott létre 2013-ban a szabványos android.util.Log alternatívájaként. A Timber kulcsgondolata — a statikus Log API lecserélése kötelező kézi tag-ről automatikus mechanizmusra, amely a hívás forrását a verem segítségével határozza meg.

A könyvtár a Composite fákkal (Tree) architekturális mintára épül. Egyetlen, rögzített viselkedésű Log osztály helyett a Timber egy „erdőt“ kezel a fákból — minden fa a saját kimeneti csatornájáért felelős: konzol, fájl, Crashlytics, távoli szerver. A fejlesztő tetszőleges számú fát adhat hozzá és kombinálhatja őket.

A Google I/O 2019 adatai szerint a Google a Timber-t ajánlja legjobb gyakorlatként a naplózáshoz Android alkalmazásokban. A könyvtár kevesebb mint 10 KB-ot foglal az APK-ban, és nincsenek külső függőségei, ami ideális választássá teszi bármilyen méretű projektek számára.

A Timber megoldja a következetlen tag-ek problémáját nagy csapatokban. Amikor minden fejlesztő kézzel írja a tag-et, a gépelési hibák és eltérések elkerülhetetlenek — az egyik osztály „MainActivity”-ként, a másik „MAIN_ACTIVITY”-ként naplózódik. A Timber automatikusan kinyeri a tag-et az osztály nevéből:MainActivity.kt → tag MainActivity.

A Timber architektúrája: fák és erdő

A Timber architektúrája két komponensből áll: a központi statikus Timber osztályból és az absztrakt Timber.Tree osztályból. A Timber homlokzatként működik, amely minden naplóhívást delegál az összes ültetett (planted) fához. Minden fa eldönti, hogy fel kell-e dolgoznia az üzenetet, és ha igen — hová irányítsa.

DebugTree — beépített implementáció fejlesztéshez

DebugTree — a könyvtárral szállított szabványos Tree implementáció. A tag-et a hívási verem elemzésével határozza meg: 8 kerettel feljebb lép a Timber.d() hívási pontjától, és megkeresi a naplózási metódust meghívó osztály nevét. A DebugTree automatikusan kikapcsol (semmit sem ír ki) release verziókban, mert ellenőrzi a BuildConfig.DEBUG-ot.

Az „erdő“ működési elve

Forest (erdő) — az összes ültetett fa gyűjteménye. Amikor a Timber.d(„üzenet”) metódus meghívódik, a könyvtár iteratívan továbbítja az üzenetet az összes fának az ültetés sorrendjében. Minden fa szűrheti az üzenetet szint, tag vagy tartalom szerint, és a saját módján dolgozhatja fel.

Az ültetés sorrendje fontos: az elsőként ültetett fa dolgozódik fel először. Javasolt a DebugTree-t utolsóként ültetni, hogy az egyedi fák (pl. Crashlytics) feldolgozzák az üzenetet, mielőtt az a Logcat-be kerül.

Szálbiztonság

A Timber szálbiztos — minden metódus szinkronizálva van egy belső lock segítségével. Ez garantálja, hogy a különböző szálakból érkező üzenetek nem keverednek össze. Az egyedi fán belül azonban a szinkronizáció a fejlesztő felelőssége: ha a fa fájlba ír, synchronized vagy ReentrantLock használata szükséges.

kotlin
// Fák erdejének inicializálása az Application.onCreate-ben
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")
    }
}

A Timber telepítése és beállítása Android projektben

A Timber telepítése egyetlen függőség hozzáadásával történik a build.gradle-ben. A könyvtár a Maven Central-ben jelent meg a com.jakewharton.timber:timber artifact alatt. Aktuális verzió 2024-re — 5.0.1, az utolsó stabil frissítés.

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

Minimális beállítás telepítés után — a DebugTree ültetése az Application.onCreate-ben. E lépés nélkül a Timber figyelmen kívül hagyja az összes naplóhívást, kivételek dobása nélkül. Ez egy biztonságos alapértelmezett viselkedés: ha a fa nincs ültetve, a könyvtár minimális overhead-del üresen működik.

Jake Wharton, 2023 adatai szerint az új felhasználók Timber-rel kapcsolatos problémáinak 70%-a az elfelejtett vagy helytelen inicializáláshoz kapcsolódik. A Timber nem generál hibát a fák hiányában — a fejlesztők azt várják, hogy a naplók megjelennek a Logcat-ben, de semmi sem történik.

Teszteléshez a Timber a Timber.asTree() metódust biztosítja — amely visszaadja az aktuális fát vagy null-t. Ez kényelmes az egységtesztekben történő ellenőrzéshez: a fa helyettesíthető egy mock-kal, és ellenőrizhető, hogy a naplóüzenet a megfelelő szinttel és tag-gel lett elküldve.

Saját Tree létrehozása egyéni naplófeldolgozáshoz

Egyedi fa — a fő ok a Timber használatára a szabványos Log API helyett. A Tree metódusainak felülírásával bármely szintű napló irányítható a Crashlytics-be, fájlrendszerbe, Remote Config-ba vagy saját szerverre.

kotlin
class CrashReportingTree : Timber.Tree() {

    override fun isLoggable(tag: String?, priority: Int): Boolean {
        // Csak Error és WTF a crash-reportinghoz
        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")
        }
    }
}

Felülírható metódusok: isLoggable(tag, priority) — szűrő, amely meghatározza, hogy az üzenetet fel kell-e dolgozni (az alap implementáció true-t ad vissza). log(priority, tag, message, t) — a feldolgozás fő logikája. prepareLog(priority, tag, throwable, message, args) — a formázás előtt hívódik meg, lehetővé teszi az üzenet módosítását a feldolgozás előtt.

Az egyedi fák fontos előnye — a reflexió hiánya. Sok naplózási keretrendszerrel ellentétben a Timber nem használ Reflection API-t a tag vagy a szint meghatározásához. A tag a hívási verem elemzésével (Throwable.stackTrace) számítható ki, ami nagyságrenddel gyorsabban működik.

Timber vs szabványos android.util.Log

A Timber és a szabványos Log API összehasonlítása négy kulcsfontosságú különbséget mutat: automatikus tag, string formázás támogatása varargs-szal, több kimeneti csatorna lehetősége és biztonságos viselkedés inicializálás hiányában.

Paraméterandroid.util.LogTimber
Tag meghatározásaKézi, string konstansAutomatikus, hívási verem alapján
FormázásÖsszefűzés vagy String.formatBeépített varargs + %s helyőrző
Kimeneti csatornákCsak LogcatFák: Logcat, fájl, Crashlytics stb.
Viselkedés inicializálás nélkülMindig működikSemmit sem ír ki
TeljesítményAlap szintLusta formázás isLoggable segítségével

Fő érv a Timber ellen — függőség egy harmadik féltől származó könyvtártól. Egy egyszerű, minimális naplózású projekt esetén a Timber használata túlzás lehet. Azonban a Google Play Console, 2024 adatai szerint a Google Play top-1000 alkalmazásának több mint 60%-a használja a Timber-t, ami megerősíti megbízhatóságát és hatékonyságát.

A Timber teljesítménye release verziókban nem marad el a szabványos Log API-tól. Ültetett fák hiányában a Timber.d() metódus ellenőrzi a fák jelenlétét (egy if) és visszatér — string formázás nélkül. Ez gyorsabb, mint a Log.d() összefűzéssel, ami mindig végrehajtódik.

Best practices a Timber használatánál

Első szabály — mindig ellenőrizze a Timber inicializálását a tesztekben. Használja a Timber.asTree() metódust annak ellenőrzésére, hogy a fa ültetve van-e. Az egységtesztekben ültessen TestTree-t, amely a listában tárolja az üzeneteket az assert ellenőrzésekhez.

Második szabály — ne keverje a Timber-t és az android.util.Log-ot egy projektben. Ha a projekt már használja a Timber-t, minden új naplóhívásnak azon keresztül kell mennie. A keverés az üzenetek duplikálódásához és zavarhoz vezet az elemzés során.

Harmadik szabály — ültesse a CrashReportingTree-t BuildConfig.DEBUG ellenőrzés nélkül. A DebugTree-től eltérően a crash fának mind debug, mind release módban működnie kell — ez garantálja, hogy a tesztelési hibák is bekerülnek a crash-reporting rendszerbe.

Negyedik szabály — használja a Timber beépített szintjeit: Timber.v(), Timber.d(), Timber.i(), Timber.w(), Timber.e(), Timber.wtf(). Kerülje a Timber.log() közvetlen hívását numerikus priority-vel — ez csökkenti a kód olvashatóságát és megnehezíti a refaktorálást.

Ötödik szabály — könyvtárakhoz és modulokhoz használja a Timber.tag(„CustomTag“) metódust. Ez a metódus egy ideiglenes fát ad vissza felülírt tag-gel, anélkül hogy befolyásolná a globális konfigurációt. Lehetővé teszi a naplózást könyvtári kódból egyedi azonosítóval.

Gyakran Ismételt Kérdések

Használható a Timber Android könyvtári modulban?

Igen — a Timber biztonságosan használható könyvtárakban. Ha a fa nincs ültetve az alkalmazásban, a Timber hívások nem okoznak hibákat. Könyvtárak esetén a Timber.tag(„LibraryTag“) használata javasolt a naplók forrásának azonosításához.

Hogyan határozza meg a Timber a tag-et kézi megadás nélkül?

A hívási veremen (stack trace) keresztül — a DebugTree 8 kerettel feljebb lép a Timber.d() hívási pontjától, és kinyeri az osztály nevét. A Throwable.stackTrace metódus a hívó osztály meghatározására szolgál a Reflection API költségei nélkül.

Miben különbözik a Timber a Logcat-től?

Logcat — az Android rendszersegédprogramja a naplók megtekintéséhez. Timber — könyvtár a naplók írásához. A Timber a DebugTree-n keresztül írja ki az üzeneteket a Logcat-be, de elküldheti azokat fájlokba, Crashlytics-be, Sentry-be és más csatornákba egyedi fákon keresztül.

Támogatja a Timber a Kotlin Multiplatform-ot?

Nem — a Timber az Android SDK-hoz (android.util.Log) kötődik. KMP projektekhez fontolja meg a Kermit vagy a Napier használatát — ezek többplatformos naplózási könyvtárak hasonló fa architektúrával, amelyek Androidon, iOS-en, JVM-en és JS-en működnek.

Hogyan lehet eltávolítani az összes ültetett fát a Timber-ben?

Használja a Timber.uprootAll() metódust — ez eltávolítja az összes regisztrált fát. A Timber.uproot(tree) egy adott fát távolít el. Ez hasznos a tesztekben az állapot visszaállításához a tesztmetódusok között.

Összefoglaló

  • Timber — könnyű wrapper az android.util.Log körül automatikus tag-gel és fa architektúrával
  • Tree — alapelem, minden fa meghatározza a saját naplókimeneti csatornáját
  • DebugTree — beépített implementáció a Logcat-hez, automatikusan kikapcsol release-ben
  • Custom Tree — naplókat küld a Crashlytics-be, fájlokba, szerverre vagy bármely más csatornába
  • Timber.tag() — ideiglenes tag váltás könyvtári kódhoz globális konfiguráció nélkül
  • Szálbiztonság — az összes Timber metódus szinkronizálva van, az egyedi fák saját szinkronizációt igényelnek
  • Biztonságos csend — fák hiányában a Timber nem dob kivételeket és nem fogyaszt erőforrásokat

Kulcsrakész mobilalkalmazást fejlesztünk

Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.

Projekt megbeszélése

Olvassa el is