Timber হল Android-এর জন্য একটি হালকা লগিং লাইব্রেরি যা ট্রি (Tree)-ভিত্তিক প্রসারণযোগ্য আর্কিটেকচার সহ, হাজার হাজার প্রজেক্টে স্ট্যান্ডার্ড android.util.Log-কে প্রতিস্থাপন করেছে। GitHub, 2024 অনুযায়ী, লাইব্রেরিটি 10,000-এর বেশি স্টার অর্জন করেছে এবং 1 বিলিয়নের বেশি ইনস্টল থাকা অ্যাপ্লিকেশনে ব্যবহৃত হয়। Timber Log API-এর তিনটি প্রধান সমস্যা সমাধান করে: স্বয়ংক্রিয় tag-এর অভাব, বাধ্যতামূলক isLoggable চেক এবং কলের স্থির প্রকৃতি।
মূল পয়েন্ট
Timber হল Android-এর জন্য একটি ওপেন-সোর্স লাইব্রেরি যা Jake Wharton 2013 সালে স্ট্যান্ডার্ড android.util.Log-এর বিকল্প হিসেবে তৈরি করেছিলেন। Timber-এর মূল ধারণা হল বাধ্যতামূলক ম্যানুয়াল tag সহ স্ট্যাটিক Log API-কে একটি স্বয়ংক্রিয় প্রক্রিয়া দিয়ে প্রতিস্থাপন করা যা স্ট্যাকের মাধ্যমে কলের উৎস নির্ধারণ করে।
লাইব্রেরিটি গাছের সাথে কম্পোজিট আর্কিটেকচারাল প্যাটার্নের উপর নির্মিত। নির্দিষ্ট আচরণ সহ একটি একক Log ক্লাসের পরিবর্তে, Timber গাছের একটি "জঙ্গল" পরিচালনা করে — প্রতিটি গাছ নিজস্ব আউটপুট চ্যানেলের জন্য দায়ী: কনসোল, ফাইল, Crashlytics, রিমোট সার্ভার। ডেভেলপার যেকোনো সংখ্যক গাছ যোগ করতে এবং সেগুলো একত্রিত করতে পারেন।
Google I/O 2019 অনুযায়ী, Google Android অ্যাপ্লিকেশনে লগিংয়ের জন্য সেরা অনুশীলন হিসেবে Timber-কে সুপারিশ করে। লাইব্রেরিটি APK-তে 10 KB-এর কম জায়গা নেয় এবং এর কোনো বাহ্যিক নির্ভরতা নেই, যা এটিকে যেকোনো স্কেলের প্রজেক্টের জন্য আদর্শ পছন্দ করে তোলে।
Timber বড় টিমে অসামঞ্জস্যপূর্ণ tag-এর সমস্যা সমাধান করে। যখন প্রতিটি ডেভেলপার ম্যানুয়ালি tag লেখে, তখন টাইপো এবং অমিল অনিবার্য — একটি ক্লাস "MainActivity" হিসেবে লগ হয়, অন্যটি "MAIN_ACTIVITY" হিসেবে। Timber স্বয়ংক্রিয়ভাবে ক্লাস নাম থেকে tag বের করে: MainActivity.kt → tag MainActivity।
আর্কিটেকচার Timber-এর দুটি উপাদান নিয়ে গঠিত: কেন্দ্রীয় স্ট্যাটিক ক্লাস Timber এবং অ্যাবস্ট্র্যাক্ট ক্লাস Timber.Tree। Timber একটি ফেসেড হিসেবে কাজ করে যা প্রতিটি লগ কল সমস্ত রোপিত গাছের কাছে অর্পণ করে। প্রতিটি গাছ সিদ্ধান্ত নেয় যে বার্তাটি প্রক্রিয়া করবে কিনা, এবং যদি হ্যাঁ, তাহলে এটি কোথায় পাঠাবে।
DebugTree হল লাইব্রেরির সাথে অন্তর্ভুক্ত স্ট্যান্ডার্ড Tree বাস্তবায়ন। এটি কল স্ট্যাক বিশ্লেষণ করে tag নির্ধারণ করে: এটি Timber.d() কল পয়েন্ট থেকে 8 ফ্রেম উপরে যায় এবং সেই ক্লাসের নাম খুঁজে পায় যা লগ মেথডকে কল করেছে। DebugTree রিলিজ বিল্ডে স্বয়ংক্রিয়ভাবে নিষ্ক্রিয় হয় (কিছুই আউটপুট করে না) কারণ এটি BuildConfig.DEBUG চেক করে।
Forest (বন) — সমস্ত রোপিত গাছের সংগ্রহ। যখন Timber.d("message") মেথড কল করা হয়, লাইব্রেরি বার্তাটিকে তাদের রোপণের ক্রমে সমস্ত গাছে পুনরাবৃত্তিমূলকভাবে পাঠায়। প্রতিটি গাছ স্তর, tag বা বিষয়বস্তু অনুসারে বার্তাটি ফিল্টার করতে পারে এবং নিজস্ব উপায়ে প্রক্রিয়া করতে পারে।
রোপণের ক্রম গুরুত্বপূর্ণ: প্রথম রোপিত গাছ প্রথমে প্রক্রিয়া হয়। DebugTree শেষে রোপণের পরামর্শ দেওয়া হয়, যাতে কাস্টম গাছগুলি (যেমন Crashlytics) Logcat-এ পৌঁছানোর আগে বার্তাটি প্রক্রিয়া করতে পারে।
Timber থ্রেড-সেফ — সমস্ত মেথড অভ্যন্তরীণ লকের মাধ্যমে সিঙ্ক্রোনাইজ করা হয়। এটি নিশ্চিত করে যে বিভিন্ন থ্রেডের বার্তা মিশে যাবে না। তবে, কাস্টম গাছের ভিতরে, সিঙ্ক্রোনাইজেশন ডেভেলপারের দায়িত্ব: যদি গাছ ফাইলে লেখে, তাহলে synchronized বা ReentrantLock ব্যবহার করতে হবে।
// 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-এর build.gradle-এ একটি নির্ভরতা যোগ করে করা হয়। লাইব্রেরিটি Maven Central-এ com.jakewharton.timber:timber আর্টিফ্যাক্টের অধীনে প্রকাশিত। 2024 পর্যন্ত বর্তমান সংস্করণ 5.0.1, সর্বশেষ স্থিতিশীল আপডেট।
// build.gradle (Module: app)
dependencies {
implementation 'com.jakewharton.timber:timber:5.0.1'
}
ইনস্টলেশনের পর ন্যূনতম সেটআপ — Application.onCreate-এ DebugTree রোপণ করা। এই ধাপ ছাড়া, Timber কোনো ব্যতিক্রম না ছুঁড়ে সমস্ত লগ কল উপেক্ষা করবে। এটি নিরাপদ ডিফল্ট আচরণ: যদি কোনো গাছ রোপণ না করা হয়, লাইব্রেরিটি ন্যূনতম ওভারহেডের সাথে নিষ্ক্রিয়ভাবে চলে।
Jake Wharton, 2023 অনুযায়ী, নতুন ব্যবহারকারীদের জন্য 70% Timber সমস্যা ভুলে যাওয়া বা ভুল ইনিশিয়ালাইজেশনের সাথে সম্পর্কিত। যখন কোনো গাছ নেই তখন Timber কোনো ত্রুটি তৈরি করে না — ডেভেলপাররা Logcat-এ লগ দেখার আশা করে, কিন্তু কিছুই ঘটে না।
পরীক্ষার জন্য, Timber Timber.asTree() প্রদান করে — একটি মেথড যা বর্তমান গাছ বা null ফেরত দেয়। এটি ইউনিট পরীক্ষার জন্য সুবিধাজনক: আপনি গাছটিকে mock দিয়ে প্রতিস্থাপন করতে পারেন এবং যাচাই করতে পারেন যে লগ বার্তাটি সঠিক স্তর এবং tag সহ পাঠানো হয়েছিল।
কাস্টম গাছ — স্ট্যান্ডার্ড Log API-এর পরিবর্তে Timber ব্যবহার করার মূল কারণ। Tree মেথড ওভাররাইড করে, আপনি যেকোনো স্তরের লগ Crashlytics, ফাইল সিস্টেম, Remote Config বা নিজস্ব সার্ভারে রুট করতে পারেন।
class CrashReportingTree : Timber.Tree() {
override fun isLoggable(tag: String?, priority: Int): Boolean {
// ক্র্যাশ-রিপোর্টিংয়ের জন্য শুধু Error এবং 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")
}
}
}
ওভাররাইড করার মেথড: isLoggable(tag, priority) — একটি ফিল্টার যা নির্ধারণ করে বার্তাটি প্রক্রিয়া করতে হবে কিনা (বেস বাস্তবায়ন true ফেরত দেয়)। log(priority, tag, message, t) — প্রধান প্রক্রিয়াকরণ লজিক। prepareLog(priority, tag, throwable, message, args) — ফরম্যাটিংয়ের আগে কল করা হয়, বার্তাটি প্রক্রিয়াকরণের আগে সংশোধন করার অনুমতি দেয়।
কাস্টম গাছের একটি গুরুত্বপূর্ণ সুবিধা হল কোনো রিফ্লেকশন নেই। অনেক লগিং ফ্রেমওয়ার্কের বিপরীতে, Timber tag বা স্তর নির্ধারণ করতে Reflection API ব্যবহার করে না। tag কল স্ট্যাক (Throwable.stackTrace) বিশ্লেষণের মাধ্যমে গণনা করা হয়, যা কয়েকগুণ দ্রুত কাজ করে।
তুলনা Timber এবং স্ট্যান্ডার্ড Log API-এর চারটি মূল পার্থক্য দেখায়: স্বয়ংক্রিয় tag, varargs সহ স্ট্রিং ফরম্যাটিং সমর্থন, একাধিক আউটপুট চ্যানেল এবং ইনিশিয়ালাইজেশন ছাড়া নিরাপদ আচরণ।
| প্যারামিটার | android.util.Log | Timber |
|---|---|---|
| Tag সনাক্তকরণ | ম্যানুয়াল, স্ট্রিং ধ্রুবক | স্বয়ংক্রিয়, কল স্ট্যাকের মাধ্যমে |
| ফরম্যাটিং | কনক্যাটেনেশন বা String.format | অন্তর্নির্মিত varargs + %s প্লেসহোল্ডার |
| আউটপুট চ্যানেল | শুধু Logcat | গাছ: Logcat, ফাইল, Crashlytics, ইত্যাদি |
| ইনিশিয়ালাইজেশন ছাড়া আচরণ | সবসময় কাজ করে | কিছুই আউটপুট করে না |
| পারফরম্যান্স | বেস লেভেল | isLoggable-এর মাধ্যমে লেজি ফরম্যাটিং |
Timber-এর বিরুদ্ধে প্রধান যুক্তি — তৃতীয় পক্ষের লাইব্রেরির উপর নির্ভরতা। ন্যূনতম লগিং সহ একটি সাধারণ প্রজেক্টের জন্য, Timber ব্যবহার অতিরিক্ত হতে পারে। তবে, Google Play Console, 2024 অনুযায়ী, Google Play-তে শীর্ষ 1000 অ্যাপের 60% এর বেশি Timber ব্যবহার করে, যা এর নির্ভরযোগ্যতা এবং দক্ষতা নিশ্চিত করে।
রিলিজ বিল্ডে Timber-এর কর্মক্ষমতা স্ট্যান্ডার্ড Log API-এর সমান। যখন কোনো গাছ রোপণ করা নেই, Timber.d() মেথড গাছের উপস্থিতি পরীক্ষা করে (একটি if) এবং ফিরে আসে — স্ট্রিং ফরম্যাটিং ছাড়া। এটি Log.d()-এর চেয়ে দ্রুত যা সবসময় সম্পাদিত হয়।
প্রথম নিয়ম — পরীক্ষায় সবসময় Timber ইনিশিয়ালাইজেশন চেক করুন। একটি গাছ রোপণ করা হয়েছে কিনা তা যাচাই করতে Timber.asTree() ব্যবহার করুন। ইউনিট পরীক্ষায়, TestTree রোপণ করুন যা assert চেকের জন্য বার্তাগুলো একটি তালিকায় সংরক্ষণ করে।
দ্বিতীয় নিয়ম — একই প্রজেক্টে Timber এবং android.util.Log মিশাবেন না। যদি প্রজেক্ট ইতিমধ্যে Timber ব্যবহার করে, তবে সমস্ত নতুন লগ কল এর মাধ্যমে হওয়া উচিত। মিশ্রণ ডুপ্লিকেট বার্তা এবং বিশ্লেষণের সময় বিভ্রান্তির সৃষ্টি করে।
তৃতীয় নিয়ম — BuildConfig.DEBUG চেক না করে CrashReportingTree রোপণ করুন। DebugTree-এর বিপরীতে, ক্র্যাশ গাছ debug এবং release উভয় ক্ষেত্রেই কাজ করা উচিত — এটি নিশ্চিত করে যে পরীক্ষার ত্রুটিগুলিও ক্র্যাশ-রিপোর্টিং সিস্টেম দ্বারা ক্যাপচার করা হয়।
চতুর্থ নিয়ম — অন্তর্নির্মিত Timber স্তর ব্যবহার করুন: Timber.v(), Timber.d(), Timber.i(), Timber.w(), Timber.e(), Timber.wtf()। সংখ্যাসূচক প্রাধান্য সহ সরাসরি Timber.log() কল করা এড়িয়ে চলুন — এটি কোড পড়ার যোগ্যতা হ্রাস করে এবং রিফ্যাক্টরিং জটিল করে।
পঞ্চম নিয়ম — লাইব্রেরি এবং মডিউলের জন্য, Timber.tag("CustomTag") ব্যবহার করুন। এই মেথডটি গ্লোবাল কনফিগারেশনকে প্রভাবিত না করে ওভাররাইড করা tag সহ একটি অস্থায়ী গাছ ফেরত দেয়। এটি কাস্টম আইডেন্টিফায়ার সহ লাইব্রেরি কোড থেকে লগিং করার অনুমতি দেয়।
প্রায়শই জিজ্ঞাসিত প্রশ্ন
হ্যাঁ — Timber লাইব্রেরিতে ব্যবহার করা নিরাপদ। যদি অ্যাপ্লিকেশনে কোনো গাছ রোপণ না করা হয়, Timber কল ত্রুটি সৃষ্টি করে না। লাইব্রেরির জন্য, লগের উৎস সনাক্ত করতে Timber.tag("LibraryTag") ব্যবহার করার পরামর্শ দেওয়া হয়।
কল স্ট্যাকের (stack trace) মাধ্যমে — DebugTree Timber.d() কল পয়েন্ট থেকে 8 ফ্রেম উপরে যায় এবং ক্লাস নাম বের করে। Throwable.stackTrace মেথড Reflection API ওভারহেড ছাড়া কলিং ক্লাস নির্ধারণ করতে ব্যবহৃত হয়।
Logcat লগ দেখার জন্য একটি Android সিস্টেম ইউটিলিটি। Timber লগ লেখার জন্য একটি লাইব্রেরি। Timber DebugTree-এর মাধ্যমে Logcat-এ বার্তা পাঠায়, তবে কাস্টম গাছের মাধ্যমে সেগুলো ফাইল, Crashlytics, Sentry এবং অন্যান্য চ্যানেলে পাঠাতে পারে।
না — Timber Android SDK (android.util.Log)-এর সাথে আবদ্ধ। KMP প্রজেক্টের জন্য, Kermit বা Napier বিবেচনা করুন — অনুরূপ গাছ আর্কিটেকচার সহ মাল্টিপ্ল্যাটফর্ম লগিং লাইব্রেরি, যা Android, iOS, JVM এবং JS-এ কাজ করে।
Timber.uprootAll() ব্যবহার করুন — মেথডটি সমস্ত নিবন্ধিত গাছ সরিয়ে দেয়। Timber.uproot(tree) একটি নির্দিষ্ট গাছ সরায়। এটি পরীক্ষা পদ্ধতির মধ্যে অবস্থা রিসেট করার জন্য পরীক্ষায় কার্যকর।
সারাংশ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন