Timber क्यों?
Android का डिफ़ॉल्ट Log क्लास वर्बोज़ है और रिलीज़ बिल्ड में लॉग्स को अक्षम करने का कोई अंतर्निहित तरीका नहीं है। Timber (Jake Wharton द्वारा) एक लाइटवेट वॉपर है जो:
- टैग स्वचालित रूप से क्लास नाम से जनरेट करता है
- रिलीज़ बिल्ड में लॉग्स को आसानी से अक्षम करता है
- कस्टम ट्री के साथ एक्सटेंसिबल है (फाइल, क्रैशलिटिक्स, आदि)
- स्ट्रिंग फॉर्मेटिंग और एक्सेप्शन हैंडलिंग सरल करता है
सेटअप
// build.gradle (Module: app)
dependencies {
implementation 'com.jakewharton.timber:timber:5.0.1'
}
आरंभीकरण (Application क्लास में)
import android.app.Application;
import timber.log.Timber;
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
if (BuildConfig.DEBUG) {
// डिबग बिल्ड: लॉगकैट में लॉग करें
Timber.plant(new Timber.DebugTree());
} else {
// रिलीज़ बिल्ड: क्रैश रिपोर्टिंग सेवा को भेजें
Timber.plant(new ReleaseTree());
}
}
// कस्टम ट्री उदाहरण: क्रैशलिटिक्स/फायरबेस के लिए
private static class ReleaseTree extends Timber.Tree {
@Override
protected void log(int priority, @Nullable String tag, @Nullable String message, @Nullable Throwable t) {
if (priority == Log.VERBOSE || priority == Log.DEBUG || priority == Log.INFO) {
return; // केवल चेतावनी/एरर भेजें
}
// FirebaseCrashlytics.getInstance().recordException(t);
// या अन्य रिमोट लॉगिंग सेवा
}
}
}
AndroidManifest.xml में एप्लिकेशन क्लास रजिस्टर करें
<application
android:name=".MyApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name">
<!-- ... -->
</application>
उपयोग उदाहरण
import timber.log.Timber;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// विभिन्न लॉग लेवल
Timber.v("वर्बोज़: विस्तृत डिबग जानकारी");
Timber.d("डिबग: फ्लो ट्रेसिंग %s", "मान");
Timber.i("इन्फो: सामान्य जानकारी - उपयोगकर्ता लॉगिन: %s", userEmail);
Timber.w("चेतावनी: संभावित समस्या - कैश मिस");
Timber.e("एरर: गंभीर विफलता");
// एक्सेप्शन लॉगिंग (स्टैक ट्रेस सहित)
try {
riskyOperation();
} catch (Exception e) {
Timber.e(e, "ऑपरेशन विफल: %s", e.getMessage());
}
// लेजी लॉगिंग (लैम्ब्डा - केवल अगर लॉग होगा)
Timber.d(() -> "महंगा ऑपरेशन परिणाम: " + expensiveComputation());
}
}
उन्नत: कस्टम ट्री बनाना
फाइल लॉगिंग ट्री
public class FileLoggingTree extends Timber.Tree {
private final File logFile;
public FileLoggingTree(File logFile) {
this.logFile = logFile;
}
@Override
protected void log(int priority, @Nullable String tag, @Nullable String message, @Nullable Throwable t) {
if (message == null && t == null) return;
String logEntry = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.US).format(new Date())
+ " " + priorityToString(priority)
+ "/" + (tag != null ? tag : "UNKNOWN")
+ ": " + message;
if (t != null) {
logEntry += "\n" + Log.getStackTraceString(t);
}
try (FileWriter fw = new FileWriter(logFile, true);
BufferedWriter bw = new BufferedWriter(fw)) {
bw.write(logEntry);
bw.newLine();
} catch (IOException e) {
// चुपचाप विफल
}
}
private String priorityToString(int priority) {
switch (priority) {
case Log.VERBOSE: return "V";
case Log.DEBUG: return "D";
case Log.INFO: return "I";
case Log.WARN: return "W";
case Log.ERROR: return "E";
case Log.ASSERT: return "A";
default: return "?";
}
}
}
// उपयोग: Timber.plant(new FileLoggingTree(new File(getFilesDir(), "app.log")));
रंगीन लॉगकैट ट्री (डिबग के लिए)
public class ColorDebugTree extends Timber.Tree {
private static final String[] COLORS = {
"\u001B[35m", // V - मैजेंटा
"\u001B[34m", // D - नीला
"\u001B[32m", // I - हरा
"\u001B[33m", // W - पीला
"\u001B[31m", // E - लाल
"\u001B[31;1m" // A - बोल्ड लाल
};
private static final String RESET = "\u001B[0m";
@Override
protected void log(int priority, @Nullable String tag, @Nullable String message, @Nullable Throwable t) {
String color = COLORS[Math.min(priority / 3, COLORS.length - 1)];
String log = color + "[" + priorityToString(priority) + "] " + tag + ": " + message + RESET;
System.out.println(log);
if (t != null) System.out.println(Log.getStackTraceString(t));
}
}
Timber vs Log तुलना
| विशेषता | android.util.Log | Timber |
|---|---|---|
| ऑटो टैग | नहीं (मैन्युअल) | हाँ (क्लास नाम) |
| रिलीज़ में अक्षम | मैन्युअल | आसान (प्लांट न करें) |
| एक्सेप्शन सपोर्ट | Log.e(tag, msg, e) | Timber.e(e, msg) |
| स्ट्रिंग फॉर्मेटिंग | String.format | बिल्ट-इन %s सपोर्ट |
| एक्सटेंसिबिलिटी | नहीं | कस्टम Tree |
सर्वोत्तम अभ्यास
- Application क्लास में एक बार
Timber.plant()करें - डिबग बिल्ड में
DebugTree, रिलीज़ में कस्टम ट्री उपयोग करें - एक्सेप्शन के लिए
Timber.e(exception, "संदेश")पैटर्न उपयोग करें - संवेदनशील डेटा (पासवर्ड, टोकन) लॉग न करें
- प्रदर्शन के लिए लैम्ब्डा सिंटैक्स
Timber.d(() -> "msg")उपयोग करें