# Logger Deployment & Usage Guide
A comprehensive guide for integrating and deploying the `orhanobut/logger` Android logging library.
## 1. Prerequisites
- **Android Studio**: Arctic Fox (2020.3.1) or later
- **Android SDK**: Minimum API level 16 (Android 4.1)
- **Build System**: Gradle 6.0+ with Android Gradle Plugin 4.0+
- **Language**: Java 8+ or Kotlin
- **Dependencies**: AndroidX annotations library (transitively included)
- **Permissions** (for file logging): `WRITE_EXTERNAL_STORAGE` (for API < 29) or appropriate scoped storage configuration
## 2. Installation
Add the dependency to your module-level `build.gradle`:
```groovy
dependencies {
implementation 'com.orhanobut:logger:2.2.0'
}
For Kotlin DSL (build.gradle.kts):
dependencies {
implementation("com.orhanobut:logger:2.2.0")
}
Sync your project with Gradle files.
3. Configuration
Basic Initialization
Initialize Logger in your Application class:
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
// Basic setup - logs to Logcat only
Logger.addLogAdapter(new AndroidLogAdapter());
}
}
Advanced Formatting Configuration
Configure PrettyFormatStrategy for custom output:
FormatStrategy formatStrategy = PrettyFormatStrategy.newBuilder()
.showThreadInfo(false) // Hide thread info (default: true)
.methodCount(2) // Show 2 method lines in stack trace (default: 2)
.methodOffset(5) // Offset to hide internal method calls (default: 5)
.tag("MyCustomTag") // Global tag (default: PRETTY_LOGGER)
.logStrategy(new LogcatLogStrategy()) // Custom log strategy (optional)
.build();
Logger.addLogAdapter(new AndroidLogAdapter(formatStrategy));
Production Configuration
Disable logging in release builds:
Logger.addLogAdapter(new AndroidLogAdapter() {
@Override
public boolean isLoggable(int priority, String tag) {
return BuildConfig.DEBUG;
}
});
File Logging Setup
Configure CSV file logging with custom tags:
// Requires WRITE_EXTERNAL_STORAGE permission on API < 29
FormatStrategy csvFormatStrategy = CsvFormatStrategy.newBuilder()
.tag("app_logs")
.build();
Logger.addLogAdapter(new DiskLogAdapter(csvFormatStrategy));
AndroidManifest.xml (for API 28 and below):
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="28" />
4. Build & Run
Basic Usage
// Simple logging
Logger.d("Debug message");
Logger.e("Error message");
Logger.w("Warning message");
Logger.i("Information");
Logger.v("Verbose");
Logger.wtf("What a Terrible Failure");
// String formatting
Logger.d("Hello %s, you have %d new messages", "User", 5);
Structured Data Logging
// Collections (Debug only)
Logger.d(hashMap);
Logger.d(arrayList);
Logger.d(hashSet);
Logger.d(stringArray);
// JSON formatting
String json = "{\"key\":\"value\",\"array\":[1,2,3]}";
Logger.json(json);
// XML formatting
String xml = "<root><item>value</item></root>";
Logger.xml(xml);
Temporary Tagging
// One-time tag usage
Logger.t("NETWORK").d("Request initiated");
Timber Integration
Timber.plant(new Timber.DebugTree() {
@Override
protected void log(int priority, String tag, String message, Throwable t) {
Logger.log(priority, tag, message, t);
}
});
Note: Set methodOffset to 5 in PrettyFormatStrategy when using Timber to hide internal Timber method calls.
5. Deployment
Release Build Configuration
ProGuard/R8 Rules (if minification enabled):
# Logger uses reflection for stack trace inspection
-keep class com.orhanobut.logger.** { *; }
-dontwarn com.orhanobut.logger.**
Disable Debug Logging in Production:
Ensure isLoggable returns false for release builds to prevent log leakage:
Logger.addLogAdapter(new AndroidLogAdapter() {
@Override
public boolean isLoggable(int priority, String tag) {
return BuildConfig.DEBUG; // Only log in debug builds
}
});
Building Release APK/AAB
# Build release APK
./gradlew assembleRelease
# Build release AAB (Google Play)
./gradlew bundleRelease
Log File Retrieval (Disk Logging)
If using DiskLogAdapter, logs are written to:
/sdcard/Android/data/[package]/logs/
Retrieve via:
adb shell run-as com.your.package cat /sdcard/Android/data/com.your.package/logs/app_logs.csv
Or use Android Studio's Device File Explorer.
6. Troubleshooting
Logs Not Appearing in Logcat
Issue: No output visible in Android Studio Logcat window.
Solutions:
- Ensure
Logger.addLogAdapter(new AndroidLogAdapter())is called before logging - Disable the "Wrap" option in Android Studio Logcat settings
- Use filter
tag:PRETTY_LOGGERor your custom tag in Logcat search - Check that
isLoggable()returnstruefor your build type
File Logging Permission Denied
Issue: DiskLogAdapter fails to write on Android 10+ (API 29+).
Solution:
- For API 29+: Use
Context.getExternalFilesDir()path (handled automatically by library) - For API 28 and below: Ensure
WRITE_EXTERNAL_STORAGEpermission is granted at runtime
Stack Trace Shows Wrong Method
Issue: Method count shows internal Logger calls instead of caller.
Solution: Adjust methodOffset in PrettyFormatStrategy:
.methodOffset(7) // Increase offset to skip Logger internal methods
JSON/XML Not Pretty Printed
Issue: JSON output appears as single line.
Solution: Ensure input is valid JSON/XML. Invalid content falls back to standard debug logging.
Logcat Truncation
Issue: Long logs are truncated.
Solution: Logger automatically chunks messages at 4000 bytes (Android log limit). If still truncated, check Android Studio's "Cycle Buffer Size" setting (default 1024 KB).
Duplicate Logs
Issue: Messages appear multiple times.
Solution: Ensure Logger.addLogAdapter() is called only once (e.g., in Application.onCreate()), not in Activity lifecycle methods.