Timber — wat is het, API van de bibliotheek en gebruiksvoorbeelden

Auteur: IT Sectr Gepubliceerd: 2026-05-28 Leestijd: 8 min

Timber — een lichte loggingbibliotheek voor Android met een uitbreidbare architectuur op basis van bomen (Tree), die de standaard android.util.Log in duizenden projecten heeft vervangen. Volgens gegevens van GitHub, 2024 heeft de bibliotheek meer dan 10.000 sterren verzameld en wordt gebruikt in apps met een publiek van meer dan 1 miljard installaties. Timber lost drie hoofdproblemen van Log API op: het ontbreken van automatische tag, verplichte isLoggable-controle en de statische aard van aanroepen.

Belangrijkste punten

  • Timber — een wrapper rond android.util.Log met automatische tag-bepaling op basis van klassenaam en call stack
  • Tree — het basiselement van Timber-architectuur, elke instantie bepaalt hoe een logbericht te verwerken
  • Bomen planten (Planting) — het proces van Tree registreren in Timber, meestal eenmalig uitgevoerd in Application.onCreate
  • DebugTree — ingebouwde implementatie voor Debug-builds, logt naar Logcat met tag uit klassenaam
  • Custom Tree — mogelijkheid om eigen implementatie te maken voor het verzenden van logs naar Crashlytics, bestand of server

Wat is Timber

Timber — is een open-source bibliotheek voor Android, gemaakt door Jake Wharton in 2013 als alternatief voor de standaard android.util.Log. Het kernidee van Timber is het vervangen van de statische Log API met verplichte handmatige tag door een automatisch mechanisme dat de aanroepbron via de stack bepaalt.

De bibliotheek is gebouwd op het architectuurpatroon Composite met bomen (Tree). In plaats van een enkele Log-klasse met vast gedrag, beheert Timber een „bos“ van bomen — elke boom is verantwoordelijk voor zijn eigen uitvoerkanaal: console, bestand, Crashlytics, externe server. Ontwikkelaars kunnen elk aantal bomen toevoegen en combineren.

Volgens gegevens van Google I/O 2019, wordt Timber door Google aanbevolen als beste praktijk voor loggen in Android-apps. De bibliotheek neemt minder dan 10 KB in beslag in APK en heeft geen externe afhankelijkheden, wat het een ideale keuze maakt voor projecten van elke omvang.

Timber lost het probleem van inconsistente tags in grote teams op. Wanneer elke ontwikkelaar handmatig een tag schrijft, zijn typefouten en verschillen onvermijdelijk — de ene klasse logt als „MainActivity“, de andere als „MAIN_ACTIVITY“. Timber haalt automatisch de tag uit de klassenaam:MainActivity.kt → tag MainActivity.

Timber-architectuur: bomen en bos

De architectuur van Timber bestaat uit twee componenten: de centrale statische klasse Timber en de abstracte klasse Timber.Tree. Timber fungeert als een façade die elke log-aanroep delegeert aan alle geplante (planted) bomen. Elke boom beslist of het bericht moet worden verwerkt, en zo ja — waar het naartoe moet worden gestuurd.

DebugTree — ingebouwde implementatie voor ontwikkeling

DebugTree — de standaard Tree-implementatie die bij de bibliotheek wordt geleverd. Deze bepaalt de tag door analyse van de call stack: stijgt 8 frames omhoog vanaf het aanroeppunt van Timber.d() en vindt de klassenaam die de logmethode heeft aangeroepen. DebugTree wordt automatisch uitgeschakeld (niets uitvoeren) in release-builds omdat het BuildConfig.DEBUG controleert.

Werkingsprincipe van het „bos“

Forest (bos) — de verzameling van alle geplante bomen. Wanneer de methode Timber.d(„bericht”) wordt aangeroepen, geeft de bibliotheek het bericht iteratief door aan alle bomen in de volgorde van planten. Elke boom kan het bericht filteren op niveau, tag of inhoud en het op zijn eigen manier verwerken.

De plantvolgorde is belangrijk: de eerste geplante boom wordt als eerste verwerkt. Het wordt aanbevolen om DebugTree als laatste te planten, zodat aangepaste bomen (bijv. Crashlytics) het bericht verwerken voordat het in Logcat terechtkomt.

Draadveiligheid

Timber is draadveilig — alle methoden zijn gesynchroniseerd via een interne lock. Dit garandeert dat berichten uit verschillende threads niet door elkaar raken. Binnen een aangepaste boom valt synchronisatie echter onder verantwoordelijkheid van de ontwikkelaar: als de boom naar een bestand schrijft, moet synchronized of ReentrantLock worden gebruikt.

kotlin
// Initialisatie van het bos van bomen in 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")
    }
}

Installatie en configuratie van Timber in Android-project

Installatie van Timber gebeurt door een enkele afhankelijkheid toe te voegen in build.gradle. De bibliotheek is gepubliceerd in Maven Central onder het artifact com.jakewharton.timber:timber. Huidige versie voor 2024 — 5.0.1, laatste stabiele update.

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

Minimale configuratie na installatie — DebugTree planten in Application.onCreate. Zonder deze stap negeert Timber alle log-aanroepen, zonder uitzonderingen te gooien. Dit is veilig standaardgedrag: als er geen boom is geplant, werkt de bibliotheek stationair met minimale overhead.

Volgens gegevens van Jake Wharton, 2023 heeft 70% van de problemen met Timber bij nieuwe gebruikers te maken met vergeten of verkeerde initialisatie. Timber genereert geen fout bij afwezigheid van bomen — ontwikkelaars verwachten dat logs in Logcat verschijnen, maar er gebeurt niets.

Voor testen biedt Timber Timber.asTree() — een methode die de huidige boom of null retourneert. Dit is handig voor controle in unittesten: de boom kan worden vervangen door een mock en controleren of het logbericht met het juiste niveau en tag is verzonden.

Eigen Tree maken voor aangepaste logverwerking

Aangepaste boom — de belangrijkste reden om Timber te gebruiken in plaats van de standaard Log API. Door het overschrijven van Tree-methoden kunnen logs van elk niveau worden omgeleid naar Crashlytics, bestandssysteem, Remote Config of een eigen server.

kotlin
class CrashReportingTree : Timber.Tree() {

    override fun isLoggable(tag: String?, priority: Int): Boolean {
        // Alleen Error en WTF voor 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")
        }
    }
}

Te overschrijven methoden: isLoggable(tag, priority) — filter dat bepaalt of het bericht moet worden verwerkt (basisimplementatie retourneert true). log(priority, tag, message, t) — de hoofdverwerkingslogica. prepareLog(priority, tag, throwable, message, args) — wordt aangeroepen vóór formattering, maakt het mogelijk het bericht te wijzigen vóór verwerking.

Een belangrijk voordeel van aangepaste bomen — geen reflectie. In tegenstelling tot veel loggingframeworks gebruikt Timber geen Reflection API voor het bepalen van tag of niveau. De tag wordt berekend via analyse van de call stack (Throwable.stackTrace), wat een orde van grootte sneller werkt.

Timber vs standaard android.util.Log

Vergelijking van Timber met de standaard Log API toont vier belangrijke verschillen: automatische tag, ondersteuning voor stringformattering met varargs, meerdere uitvoerkanalen en veilig gedrag bij afwezigheid van initialisatie.

Parameterandroid.util.LogTimber
Tag-bepalingHandmatig, stringconstanteAutomatisch, via call stack
FormatteringConcatenatie of String.formatIngebouwde varargs + placeholder %s
UitvoerkanalenAlleen LogcatBomen: Logcat, bestand, Crashlytics enz.
Gedrag zonder initialisatieWerkt altijdVoert niets uit
PrestatieBasisniveauLazy formattering via isLoggable

Belangrijkste argument tegen Timber — afhankelijkheid van een externe bibliotheek. Voor een eenvoudig project met minimale logging kan het gebruik van Timber overdreven zijn. Echter, volgens gegevens van Google Play Console, 2024 gebruikt meer dan 60% van de top-1000 apps in Google Play Timber, wat de betrouwbaarheid en effectiviteit bevestigt.

De prestaties van Timber in release-builds doen niet onder voor de standaard Log API. Bij afwezigheid van geplante bomen controleert Timber.d() de aanwezigheid van bomen (één if) en keert terug — zonder stringformattering. Dit is sneller dan Log.d() met concatenatie, die altijd wordt uitgevoerd.

Best practices bij gebruik van Timber

Eerste regel — controleer altijd de initialisatie van Timber in tests. Gebruik Timber.asTree() om te verifiëren dat de boom is geplant. Plant in unittesten TestTree die berichten in een lijst opslaat voor assert-controles.

Tweede regel — meng Timber en android.util.Log niet in hetzelfde project. Als het project al Timber gebruikt, moeten alle nieuwe log-aanroepen erdoorheen gaan. Mengen leidt tot duplicatie van berichten en verwarring bij analyse.

Derde regel — plant CrashReportingTree zonder BuildConfig.DEBUG-controle. In tegenstelling tot DebugTree moet de crash-boom zowel in debug als in release werken — dit garandeert dat testfouten ook in het crash-reporting systeem terechtkomen.

Vierde regel — gebruik de ingebouwde niveaus van Timber: Timber.v(), Timber.d(), Timber.i(), Timber.w(), Timber.e(), Timber.wtf(). Vermijd directe aanroep van Timber.log() met numerieke priority — dit vermindert de leesbaarheid van code en bemoeilijkt refactoring.

Vijfde regel — gebruik voor bibliotheken en modules Timber.tag(„CustomTag“). Deze methode retourneert een tijdelijke boom met overschreven tag, zonder de globale configuratie te beïnvloeden. Dit maakt loggen uit bibliotheekcode met een aangepaste identificatie mogelijk.

Veelgestelde vragen

Kan Timber worden gebruikt in een Android-bibliotheekmodule?

Ja — Timber is veilig te gebruiken in bibliotheken. Als er geen boom is geplant in de app, veroorzaken Timber-aanroepen geen fouten. Voor bibliotheken wordt aangeraden Timber.tag(„LibraryTag“) te gebruiken voor identificatie van de logbron.

Hoe bepaalt Timber de tag zonder handmatige opgave?

Via de call stack (stack trace) — DebugTree stijgt 8 frames omhoog vanaf het aanroeppunt van Timber.d() en haalt de klassenaam op. De methode Throwable.stackTrace wordt gebruikt om de aanroepende klasse te bepalen zonder kosten van Reflection API.

Waarin verschilt Timber van Logcat?

Logcat — het systeemhulpprogramma van Android voor het bekijken van logs. Timber — een bibliotheek voor het schrijven van logs. Timber voert berichten uit naar Logcat via DebugTree, maar kan ze ook verzenden naar bestanden, Crashlytics, Sentry en andere kanalen via aangepaste bomen.

Ondersteunt Timber Kotlin Multiplatform?

Nee — Timber is gebonden aan Android SDK (android.util.Log). Overweeg voor KMP-projecten Kermit of Napier — multiplatform loggingbibliotheken met vergelijkbare boomarchitectuur die werken op Android, iOS, JVM en JS.

Hoe verwijder ik alle geplante bomen in Timber?

Gebruik Timber.uprootAll() — deze methode verwijdert alle geregistreerde bomen. Timber.uproot(tree) verwijdert een specifieke boom. Dit is handig in tests om de status tussen testmethoden te resetten.

Samenvatting

  • Timber — lichte wrapper rond android.util.Log met automatische tag en boomarchitectuur
  • Tree — basiselement, elke boom bepaalt zijn eigen loguitvoerkanaal
  • DebugTree — ingebouwde implementatie voor Logcat, wordt automatisch uitgeschakeld in release
  • Custom Tree — stuurt logs naar Crashlytics, bestanden, server of elk ander kanaal
  • Timber.tag() — tijdelijke tagwijziging voor bibliotheekcode zonder globale configuratie
  • Draadveiligheid — alle Timber-methoden zijn gesynchroniseerd, aangepaste bomen vereisen eigen synchronisatie
  • Veilige stilte — bij afwezigheid van bomen gooit Timber geen uitzonderingen en verbruikt geen resources

We ontwikkelen een mobiele applicatie turnkey

IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.

Bespreek het project

Lees ook