Skip to content

mikeisesele/easylog

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

77 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

EasyLog

A lightweight, intelligent logging library for Android with beautiful tree-structured output and smart object detection.

✨ What's New

  • 🌳 Tree-structured output for complex objects and collections
  • πŸ” Smart object detection with automatic formatting
  • ⚑ Runtime log level filtering
  • πŸ›‘οΈ Enhanced reflection safety
  • πŸ“Š Grouped logging with logMany()
  • 🎯 Zero breaking changes - drop-in upgrade

πŸ“± Quick Start

1. Add Dependency

// build.gradle.kts (app)
implementation("com.github.mikeisesele:easylog:4.0.0")
// settings.gradle.kts
repositories {
    maven { url = uri("https://jitpack.io") }
}

2. Initialize (Application class)

class MyApp : Application() {
    override fun onCreate() {
        super.onCreate()
        
        EasyLog.setUp {
            debugMode(BuildConfig.DEBUG)
            filterTag("MyApp")  // Optional: custom tag
            minimumLogLevel(LogType.DEBUG)  // New: runtime filtering
        }
    }
}

3. Enable BuildConfig

// build.gradle.kts (app)
android {
    buildFeatures {
        buildConfig = true
    }
}

πŸš€ Usage Examples

Basic Logging

"Hello World".logD("Greeting")
42.logI("Answer")
true.logE("Boolean value")

Smart Object Formatting

data class User(val name: String, val age: Int, val emails: List<String>)

val user = User("John", 30, listOf("john@work.com", "john@personal.com"))
user.logD("User profile")

Output:

πŸ” USER PROFILE: at MainActivity.kt:45
╭─ User (com.example.model)
β”œβ”€ name: "John"
β”œβ”€ age: 30
╰─ emails: List[2]
   β”œβ”€ [0]: "john@work.com"
   ╰─ [1]: "john@personal.com"

Collections & Arrays

listOf("apple", "banana", "cherry").logD("Fruits")
arrayOf(1, 2, 3, 4, 5).logI("Numbers")

Output:

πŸ” FRUITS: at MainActivity.kt:50
╭─ List[3]
β”œβ”€ [0]: "apple"
β”œβ”€ [1]: "banana"
╰─ [2]: "cherry"

Grouped Logging

logMany(
    header = "App Configuration",
    BuildConfig.DEBUG,
    BuildConfig.VERSION_NAME,
    "Environment: Production",
    42
)

Output:

πŸ” ╭─ APP CONFIGURATION at MainActivity.kt:55
πŸ” β”œβ”€ [1] true
πŸ” β”œβ”€ [2] "1.0.0"
πŸ” β”œβ”€ [3] "Environment: Production"
πŸ” ╰─ [4] 42

Inline Logging

val result = "Processing data"
    .logInline("Step 1")
    .uppercase()
    .logInline("Step 2")

// Logs each step and returns the value for chaining

Nullable Objects

val nullableUser: User? = getUser()
nullableUser.logInlineNullable("User lookup result")

βš™οΈ Advanced Configuration

Runtime Log Filtering

// Only show warnings and errors
EasyLog.setMinimumLogLevel(LogType.WARNING)

// Check current level
val currentLevel = EasyLog.getMinimumLogLevel()

File Logging

EasyLog.setUp {
    debugMode(BuildConfig.DEBUG)
    addDefaultLogger(DefaultLogger.FILE_LOGGER)
    context(applicationContext)  // Required for file logging
}

Custom Logger

class MyCustomLogger : Logger {
    override fun log(
        logMessage: String,
        logObject: Any,
        level: LogType,
        fileName: String?,
        lineNumber: Int
    ) {
        // Your custom implementation
    }
}

EasyLog.setUp {
    addCustomLogger(MyCustomLogger())
}

πŸ“Š Log Levels

  • logV() - Verbose πŸ“
  • logD() - Debug πŸ”
  • logI() - Info ℹ️
  • logW() - Warning ⚠️
  • logE() - Error ❌
  • logWtf() - What a Terrible Failure πŸ’₯

πŸ”§ Migration from v1

Zero code changes required! EasyLog v2 is 100% backward compatible.

New Features Available:

  • Enhanced object formatting (automatic)
  • minimumLogLevel() configuration
  • logMany() function
  • Better performance and safety

Deprecated (still works):

// Old way (still works)
.defaultLogger(DefaultLogger.DEFAULT_ANDROID)

// New way (recommended)
.addDefaultLogger(DefaultLogger.DEFAULT_ANDROID)

πŸ“‹ Requirements

  • Minimum SDK: 24
  • Kotlin reflection: Auto-included
  • ProGuard: No configuration needed

🎯 Best Practices

  1. Use meaningful messages:

    user.logD("After API call")  // Good
    user.logD()  // Works, but less descriptive
  2. Filter by tag in Logcat:

    tag:MyApp
    
  3. Use appropriate log levels:

    result.logD("Debug info")      // Development
    error.logE("API failed")       // Production issues
    config.logI("App started")     // Important events
  4. Leverage inline logging:

    val processed = rawData
        .logInline("Raw data")
        .processStep1()
        .logInline("After step 1")
        .processStep2()
        .logInline("Final result")

πŸ“„ License

MIT License - see LICENSE file for details

πŸ™‹β€β™‚οΈ Support

Example Outputs

Screenshot 2025-09-19 at 8 41 15β€―PM Screenshot 2025-09-19 at 8 41 05β€―PM Screenshot 2025-09-19 at 8 40 45β€―PM

⚠️ Important Considerations Performance & Production Use

Reflection overhead: EasyLog v4 uses Kotlin reflection for enhanced object formatting, which adds computational overhead Development focus: Designed primarily for development and testing environments where debugging visibility outweighs performance concerns Production recommendations:

Use minimumLogLevel(LogType.WARNING) or higher in production builds Consider disabling complex object logging in release builds via debugMode(false) Monitor app performance when logging large or deeply nested objects

Technical Limitations

Obfuscated code: R8/ProGuard obfuscation may affect property names in formatted output Sealed classes: Some sealed classes or classes with restricted reflection access may display simplified output Memory usage: Complex object trees with circular references are handled safely but may use additional memory Thread safety: While EasyLog is thread-safe, logging very large objects concurrently may impact performance

Best Practices

Development workflow: Use detailed object logging during development and debugging phases Testing environments: Leverage full EasyLog capabilities in staging/testing environments Production deployment: Configure appropriate log levels to balance debugging needs with app performance Large datasets: Consider logging subsets or summaries of large collections rather than complete datasets

Scope & Compatibility

Android focus: Optimized for Android development workflows and Android Studio logcat integration Minimum SDK: Requires Android API 24+ due to reflection requirements Kotlin interop: Full compatibility with Kotlin data classes, sealed classes, and standard collections Java compatibility: Works with Java objects but optimal formatting designed for Kotlin constructs

Made with ❀️ by Michael Isesele

About

A lightweight library that simplifies logging on Android

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages