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, κάθε στιγμιότυπο καθορίζει πώς να επεξεργαστεί το μήνυμα καταγραφής
  • Φύτευση δέντρων (Planting) — η διαδικασία εγγραφής 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, το Timber προτείνεται από την Google ως βέλτιστη πρακτική για καταγραφή σε εφαρμογές Android. Η βιβλιοθήκη καταλαμβάνει λιγότερο από 10 KB στο APK και δεν έχει εξωτερικές εξαρτήσεις, καθιστώντας την ιδανική επιλογή για έργα οποιουδήποτε μεγέθους.

Το Timber λύνει το πρόβλημα των ασυνεπών tag σε μεγάλες ομάδες. Όταν κάθε προγραμματιστής γράφει το tag χειροκίνητα, τα τυπογραφικά λάθη και οι αποκλίσεις είναι αναπόφευκτες — η μία κλάση καταγράφεται ως “MainActivity”, η άλλη ως “MAIN_ACTIVITY”. Το Timber εξάγει αυτόματα το tag από το όνομα της κλάσης:MainActivity.kt → tag MainActivity.

Αρχιτεκτονική Timber: δέντρα και δάσος

Η αρχιτεκτονική του Timber αποτελείται από δύο στοιχεία: την κεντρική στατική κλάση Timber και την αφηρημένη κλάση Timber.Tree. Το Timber λειτουργεί ως πρόσοψη που εκχωρεί κάθε κλήση καταγραφής σε όλα τα φυτεμένα (planted) δέντρα. Κάθε δέντρο αποφασίζει αν πρέπει να επεξεργαστεί το μήνυμα, και αν ναι — πού να το κατευθύνει.

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 γίνεται προσθέτοντας μία εξάρτηση στο 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. Αυτό είναι βολικό για έλεγχο σε unit tests: το δέντρο μπορεί να αντικατασταθεί με 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 για 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")
        }
    }
}

Μέθοδοι προς παράκαμψη: isLoggable(tag, priority) — φίλτρο που καθορίζει αν πρέπει να επεξεργαστεί το μήνυμα (η βασική υλοποίηση επιστρέφει true). log(priority, tag, message, t) — η κύρια λογική επεξεργασίας. prepareLog(priority, tag, throwable, message, args) — καλείται πριν από τη μορφοποίηση, επιτρέπει την αλλαγή του μηνύματος πριν από την επεξεργασία.

Ένα σημαντικό πλεονέκτημα των προσαρμοσμένων δέντρων — απουσία ανάκλασης (reflection). Σε αντίθεση με πολλά πλαίσια καταγραφής, το Timber δεν χρησιμοποιεί Reflection API για τον προσδιορισμό tag ή επιπέδου. Το tag υπολογίζεται μέσω ανάλυσης της στοίβας κλήσεων (Throwable.stackTrace), που λειτουργεί κατά τάξη μεγέθους ταχύτερα.

Timber vs τυπικό android.util.Log

Η σύγκριση του Timber με το τυπικό Log API δείχνει τέσσερις βασικές διαφορές: αυτόματο tag, υποστήριξη μορφοποίησης συμβολοσειρών με varargs, δυνατότητα πολλαπλών καναλιών εξόδου και ασφαλή συμπεριφορά όταν απουσιάζει αρχικοποίηση.

Παράμετροςandroid.util.LogTimber
Προσδιορισμός tagΧειροκίνητος, σταθερά συμβολοσειράςΑυτόματος, βάσει στοίβας κλήσεων
ΜορφοποίησηΣυνένωση ή String.formatΕνσωματωμένο varargs + placeholder %s
Κανάλια εξόδουΜόνο LogcatΔέντρα: Logcat, αρχείο, Crashlytics κ.λπ.
Συμπεριφορά χωρίς αρχικοποίησηΛειτουργεί πάνταΔεν εξάγει τίποτα
ΑπόδοσηΒασικό επίπεδοΤεμπέλικη μορφοποίηση μέσω isLoggable

Κύριο επιχείρημα κατά του Timber — εξάρτηση από βιβλιοθήκη τρίτου μέρους. Για ένα απλό έργο με ελάχιστη καταγραφή, η χρήση του Timber μπορεί να είναι υπερβολική. Ωστόσο, σύμφωνα με στοιχεία του Google Play Console, 2024, πάνω από το 60% των top-1000 εφαρμογών στο Google Play χρησιμοποιούν το Timber, γεγονός που επιβεβαιώνει την αξιοπιστία και αποτελεσματικότητά του.

Η απόδοση του Timber σε εκδόσεις release δεν υστερεί σε σχέση με το τυπικό Log API. Όταν απουσιάζουν φυτεμένα δέντρα, η μέθοδος Timber.d() ελέγχει την παρουσία δέντρων (ένα if) και επιστρέφει — χωρίς μορφοποίηση συμβολοσειράς. Αυτό είναι ταχύτερο από το Log.d() με συνένωση, η οποία εκτελείται πάντα.

Best practices κατά τη χρήση του Timber

Πρώτος κανόνας — ελέγχετε πάντα την αρχικοποίηση του Timber στις δοκιμές. Χρησιμοποιήστε το Timber.asTree() για επαλήθευση ότι το δέντρο είναι φυτεμένο. Στα unit tests, φυτέψτε TestTree που αποθηκεύει τα μηνύματα σε μια λίστα για ελέγχους assert.

Δεύτερος κανόνας — μην αναμιγνύετε το Timber και το android.util.Log στο ίδιο έργο. Εάν το έργο χρησιμοποιεί ήδη το Timber, όλες οι νέες κλήσεις καταγραφής πρέπει να περνούν μέσα από αυτό. Η ανάμειξη οδηγεί σε διπλασιασμό μηνυμάτων και σύγχυση κατά την ανάλυση.

Τρίτος κανόνας — φυτέψτε το CrashReportingTree χωρίς έλεγχο BuildConfig.DEBUG. Σε αντίθεση με το DebugTree, το δέντρο crash πρέπει να λειτουργεί τόσο σε debug όσο και σε release — αυτό εγγυάται ότι τα σφάλματα δοκιμής θα εισέλθουν επίσης στο σύστημα crash-reporting.

Τέταρτος κανόνας — χρησιμοποιήστε τα ενσωματωμένα επίπεδα του Timber: Timber.v(), Timber.d(), Timber.i(), Timber.w(), Timber.e(), Timber.wtf(). Αποφύγετε την άμεση κλήση Timber.log() με αριθμητικό priority — αυτό μειώνει την αναγνωσιμότητα του κώδικα και περιπλέκει το refactoring.

Πέμπτος κανόνας — για βιβλιοθήκες και ενότητες, χρησιμοποιήστε το 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. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.

Συζήτηση έργου

Διαβάστε επίσης