Timber — Android üçün yüngül loqlama kitabxanasıdır, Tree (ağac) əsaslı genişləndirilə bilən arxitekturaya malikdir və minlərlə layihədə standart android.util.Log-u əvəz etmişdir. GitHub, 2024 məlumatlarına görə, kitabxana 10 000-dən çox ulduz toplamış və 1 milyarddan çox quraşdırması olan tətbiqlərdə istifadə olunur. Timber Log API-nin üç əsas problemini həll edir: avtomatik tag-in olmaması, məcburi isLoggable yoxlaması və çağırışların statik təbiəti.
Əsas məqamlar
Timber — 2013-cü ildə Ceyk Varton (Jake Wharton) tərəfindən standart android.util.Log-a alternativ olaraq yaradılmış Android üçün open-source kitabxanadır. Timber-in əsas ideyası — məcburi əl tag-i olan statik Log API-ni çağırış mənbəyini yığın üzrə təyin edən avtomatik mexanizmlə əvəz etməkdir.
Kitabxana Composite ilə ağaclar (Tree) arxitektura nümunəsi əsasında qurulmuşdur. Sabit davranışlı tək Log sinfi əvəzinə, Timber ağaclardan ibarət “meşə” idarə edir — hər ağac öz çıxış kanalına cavabdehdir: konsol, fayl, Crashlytics, uzaq server. Tərtibatçı istənilən sayda ağac əlavə edib onları birləşdirə bilər.
Google I/O 2019 məlumatlarına görə, Timber Google tərəfindən Android tətbiqlərində loqlama üçün ən yaxşı təcrübə kimi tövsiyə olunur. Kitabxana APK-da 10 KB-dan az yer tutur və xarici asılılıqları yoxdur, bu da onu istənilən miqyaslı layihələr üçün ideal seçim edir.
Timber böyük komandalarda uyğun olmayan tag problemini həll edir. Hər bir tərtibatçı tag-i əl ilə yazdıqda, səhvlər və fərqliliklər qaçılmaz olur — bir sinif “MainActivity”, digəri “MAIN_ACTIVITY” kimi loqlanır. Timber avtomatik olaraq tag-i sinif adından çıxarır:MainActivity.kt → tag MainActivity.
Timber arxitekturası iki komponentdən ibarətdir: mərkəzi statik sinif Timber və abstrakt sinif Timber.Tree. Timber fasad rolunu oynayır, hər loq çağırışını bütün əkilmiş (planted) ağaclara ötürür. Hər ağac mesajı emal edib-etməməyi, və əgər həddi varsa, hara yönləndirəcəyini qərar verir.
DebugTree — kitabxana ilə gələn standart Tree tətbiqidir. O, tag-i çağırış yığınının təhlili ilə təyin edir: Timber.d() çağırış nöqtəsindən 8 çərçivə yuxarı qalxır və loq metodunu çağıran sinifin adını tapır. DebugTree release qurğularında avtomatik olaraq sönür (heç nə çıxarmır), çünki BuildConfig.DEBUG-u yoxlayır.
Forest (meşə) — bütün əkilmiş ağacların kolleksiyası. Timber.d(“message”) metodu çağırıldıqda, kitabxana mesajı əkilmə sırası ilə bütün ağaclara iterativ şəkildə ötürür. Hər ağac mesajı səviyyəyə, tag-ə və ya məzmununa görə süzgəcdən keçirib öz üsulu ilə emal edə bilər.
Əkilmə sırası vacibdir: ilk əkilən ağac birinci emal olunur. Xüsusi ağacların (məsələn, Crashlytics) mesajı Logcat-ə düşməzdən əvvəl emal etməsi üçün DebugTree-nin sonuncu əkilməsi tövsiyə olunur.
Timber ip güvənlidir — bütün metodlar daxili kilid vasitəsilə sinxronizasiya olunur. Bu, müxtəlif iplərdən gələn mesajların qarışmamasını təmin edir. Lakin xüsusi ağac daxilində sinxronizasiya tərtibatçının öhdəsinə düşür: əgər ağac fayla yazırsa, synchronized və ya ReentrantLock istifadə edilməlidir.
// Application.onCreate-də ağac meşəsinin inicializasiyası
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-in qurulması build.gradle-ə bir asılılıq əlavə etməklə həyata keçirilir. Kitabxana Maven Central-də com.jakewharton.timber:timber artifaktı ilə nəşr olunub. 2024-cü il üçün cari versiya — 5.0.1, son sabit yeniləmə.
// build.gradle (Module: app)
dependencies {
implementation 'com.jakewharton.timber:timber:5.0.1'
}
Qurulumdan sonra minimal konfiqurasiya — Application.onCreate-də DebugTree-nin əkilməsi. Bu addım olmadan Timber heç bir istisna atmadan bütün loq çağırışlarını görməməzlikdən gələcək. Bu təhlükəsiz standart davranışdır: ağac əkilməyibsə, kitabxana minimal yüklə boş işləyir.
Jake Wharton, 2023 məlumatlarına görə, yeni istifadəçilərdə Timber ilə bağlı problemlərin 70%-i unudulmuş və ya səhv inicializasiya ilə bağlıdır. Timber ağac olmadıqda xəta yaratmır — tərtibatçılar loqların Logcat-də görünəcəyini gözləyir, lakin heç nə baş vermir.
Test üçün Timber Timber.asTree() metodunu təqdim edir — cari ağacı və ya null qaytaran metod. Bu, vahid testlərində yoxlama üçün əlverişlidir: ağacı mock ilə əvəz etmək və loq mesajının düzgün səviyyə və tag ilə göndərildiyini yoxlamaq olar.
Xüsusi ağac — standart Log API əvəzinə Timber istifadə etməyin əsas səbəbidir. Tree metodlarını dəyişdirməklə istənilən səviyyəli loqları Crashlytics-ə, fayl sisteminə, Remote Config-ə və ya öz serverinizə yönləndirə bilərsiniz.
class CrashReportingTree : Timber.Tree() {
override fun isLoggable(tag: String?, priority: Int): Boolean {
// Yalnız crash-reporting üçün Error və WTF
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")
}
}
}
Dəyişdirilə bilən metodlar: isLoggable(tag, priority) — mesajı emal etmək lazım olub-olmadığını təyin edən filtr (əsas tətbiq true qaytarır). log(priority, tag, message, t) — emalın əsas məntiqi. prepareLog(priority, tag, throwable, message, args) — formatlamadan əvvəl çağırılır, mesajı emaldan əvvəl dəyişməyə imkan verir.
Xüsusi ağacların mühüm üstünlüyü — refleksiyanın olmaması. Bir çox loqlama freymvorklarından fərqli olaraq, Timber tag və ya səviyyəni təyin etmək üçün Reflection API-dən istifadə etmir. Tag çağırış yığınının təhlili (Throwable.stackTrace) ilə hesablanır, bu da daha sürətli işləyir.
Timber və standart Log API-nin müqayisəsi dörd əsas fərqi göstərir: avtomatik tag, varargs ilə sətir formatlaması dəstəyi, çoxsaylı çıxış kanalları imkanı və inicializasiya olmadıqda təhlükəsiz davranış.
| Parametr | android.util.Log | Timber |
|---|---|---|
| Tag-in təyini | Əl ilə, sətir sabiti | Avtomatik, çağırış yığını üzrə |
| Formatlama | Konkatenasiya və ya String.format | Daxili varargs + %s yertutanı |
| Çıxış kanalları | Yalnız Logcat | Ağaclar: Logcat, fayl, Crashlytics və s. |
| Inicializasiyasız davranış | Həmişə işləyir | Heç nə çıxarmır |
| Performans | Əsas səviyyə | isLoggable vasitəsilə tənbəl formatlama |
Timber-ə qarşı əsas arqument — üçüncü tərəf kitabxanasından asılılıq. Minimal loqlama ilə sadə bir layihə üçün Timber istifadəsi həddindən artıq ola bilər. Lakin Google Play Console, 2024 məlumatlarına görə, Google Play-də top-1000 tətbiqin 60%-dən çoxu Timber istifadə edir ki, bu da onun etibarlılığını və effektivliyini təsdiqləyir.
Timber-in release qurğularında performansı standart Log API-dən geri qalmır. Əkilmiş ağaclar olmadıqda, Timber.d() metodu ağacların varlığını yoxlayır (bir if) və qayıdır — sətir formatlaması olmadan. Bu, həmişə yerinə yetirilən konkatenasiya ilə Log.d() -dən daha sürətlidir.
Birinci qayda — həmişə testlərdə Timber inicializasiyasını yoxlayın. Ağacın əkildiyini təsdiqləmək üçün Timber.asTree() istifadə edin. Vahid testlərində assert yoxlamaları üçün mesajları siyahıda saxlayan TestTree əkin.
İkinci qayda — bir layihədə Timber və android.util.Log-u qarışdırmayın. Layihə artıq Timber istifadə edirsə, bütün yeni loq çağırışları ondan keçməlidir. Qarışdırma mesajların təkrarlanmasına və analiz zamanı qarışıqlığa səbəb olur.
Üçüncü qayda — CrashReportingTree-i BuildConfig.DEBUG yoxlaması olmadan əkin. DebugTree-dən fərqli olaraq, crash ağacı həm debug, həm də release-də işləməlidir — bu, test səhvlərinin də crash-reporting sisteminə düşməsini təmin edir.
Dördüncü qayda — Timber-in daxili səviyyələrindən istifadə edin: Timber.v(), Timber.d(), Timber.i(), Timber.w(), Timber.e(), Timber.wtf(). Rəqəmsal priority ilə Timber.log()-un birbaşa çağırılmasından çəkinin — bu kodun oxunaqlılığını azaldır və refaktorinqi çətinləşdirir.
Beşinci qayda — kitabxana və modullar üçün Timber.tag(“CustomTag”) istifadə edin. Bu metod dəyişdirilmiş tag ilə müvəqqəti ağac qaytarır, qlobal konfiqurasiyaya təsir etmir. Bu, kitabxana kodundan xüsusi identifikatorla loqlamağa imkan verir.
Tez-tez verilən suallar
Bəli — Timber kitabxanalarda istifadə üçün təhlükəsizdir. Tətbiqdə ağac əkilməyibsə, Timber çağırışları xətalara səbəb olmur. Kitabxanalar üçün loq mənbəyini müəyyən etmək üçün Timber.tag(“LibraryTag”) istifadə etmək tövsiyə olunur.
Çağırış yığını (stack trace) vasitəsilə — DebugTree Timber.d() çağırış nöqtəsindən 8 çərçivə yuxarı qalxır və sinif adını çıxarır. Throwable.stackTrace metodu Reflection API xərcləri olmadan çağıran sinifi təyin etmək üçün istifadə olunur.
Logcat — loqlara baxmaq üçün sistem Android utilitidir. Timber — loq yazmaq üçün kitabxanadır. Timber DebugTree vasitəsilə mesajları Logcat-ə çıxarır, həmçinin onları fayllara, Crashlytics-ə, Sentry-ə və xüsusi ağaclar vasitəsilə digər kanallara göndərə bilər.
Xeyr — Timber Android SDK-dan (android.util.Log) asılıdır. KMP layihələri üçün Kermit və ya Napier — Android, iOS, JVM və JS-də işləyən oxşar ağac arxitekturasına malik multiplatform loqlama kitabxanalarını nəzərdən keçirin.
Timber.uprootAll() istifadə edin — bu metod bütün qeydiyyatdan keçmiş ağacları silir. Timber.uproot(tree) müəyyən bir ağacı silir. Bu, test metodları arasında vəziyyəti sıfırlamaq üçün testlərdə faydalıdır.
Xülasə
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun