drlogger
1.0.18indexedListener-based logging framework with asynchronous, thread-safe dispatch, multiple log levels, regex-based tag/message filtering, emoji console output, daily rotating file logs with cleanup, and custom listener support.
Listener-based logging framework with asynchronous, thread-safe dispatch, multiple log levels, regex-based tag/message filtering, emoji console output, daily rotating file logs with cleanup, and custom listener support.
A powerful Kotlin Multiplatform logging library designed for cross-platform applications. DR-Logger provides a flexible, listener-based logging architecture with platform-specific implementations for Android, iOS, JVM, macOS, Linux, and Windows.
import pl.dronline.utils.log.DrLogger
import pl.dronline.utils.log.listener.EmojiConsoleLogListener
// Add a console listener
DrLogger.addListener(EmojiConsoleLogListener().apply {
enabled = true
})
// Create logger instance
val logger = DrLogger("MyApp")
// Log messages
logger.debug("Application started")
logger.info("User logged in")
logger.warn("Memory usage high")
logger.error("Failed to connect to server")
logger.fatal("Critical system failure")
Logs are processed asynchronously. CLI tools, oneshot services, and other short-lived processes should flush pending messages and stop listeners before exiting:
try {
DrLogger("Updater").info("Update completed")
} finally {
DrLogger.shutdownBlocking()
}
The suspending DrLogger.shutdown() variant is available for coroutine-based code. Use DrLogger.flush() or DrLogger.flushBlocking() when listeners should remain active.
logger.d("TAG", "Debug message")
logger.i("TAG", "Info message")
logger.w("TAG", "Warning message")
logger.e("TAG", "Error message")
try {
// Some code that might throw
} catch (e: Exception) {
logger.error(e, "Failed to process request")
}
Create custom log listeners by implementing ILogListener:
class CustomLogListener : ALogListener("CustomListener") {
override suspend fun onLogMessage(message: LogMessage) {
// Handle log message
println("[${message.level}] ${message.tag}: ")
}
}
DrLogger.addListener(CustomLogListener().apply { enabled = })
import pl.dronline.utils.log.listener.DailyFileLogListener
val fileListener = DailyFileLogListener().apply {
path = "/path/to/logs" // Directory is created automatically if it doesn't exist
namePrefix = "app-" // Log files: app-20250123.log
maxFileCount = 30 // Keep max 30 files
maxFileAgeDays = 90 // Delete files older than 90 days
maxFileSize = 10.MB // Optional: 10MB max per file (nginx-style rotation)
enabled = true
}
DrLogger.addListener(fileListener)
When maxFileSize is set, files rotate nginx-style within a day:
app-20250123.log - current file (always newest)app-20250123.1.log - previous fileapp-20250123.2.log - older fileAvailable size units: 10.bytes, 500.kB, 10.MB, 1.GB
// Filter by log level
listener.minLevel = DrLogLevel.WARN
// Filter by tag pattern
listener.tagFilter = Regex("^MyApp.*")
// Filter by message pattern
listener.messageFilter = Regex(".*error.*", RegexOption.IGNORE_CASE)
No additional setup required. Logcat integration works out of the box:
DrLogger.addListener(LogcatLogListener().apply { enabled = true })
For Log4j integration:
DrLogger.addListener(Log4jLogListener().apply { enabled = true })
Make sure Log4j is configured in your application.
Install required system dependencies:
sudo apt install libsystemd-dev gcc-multilib
Use SyslogLogListener for system logging:
DrLogger.addListener(SyslogLogListener(
ident = "myapp",
facility = SyslogFacility.USER
).apply { enabled = true })
View logs with: journalctl -t myapp or tail -f /var/log/syslog
No additional setup required. Use LogcatLogListener or SyslogLogListener to write to Windows Event Log.
Both delegate to EventLogLogListener internally.
View logs using Event Viewer (eventvwr.msc) under "Windows Logs" -> "Application":
// Using LogcatLogListener (default source: "DrLogger")
DrLogger.addListener(LogcatLogListener().apply { enabled = true })
// Or using SyslogLogListener with custom source name
DrLogger.addListener(SyslogLogListener(ident = "MyApp").apply { enabled = true })
Log levels are mapped to Event Log types:
No additional setup required. Native platform logging is automatically configured.
DR-Logger uses a central dispatch system (DrLoggerFactory) that routes log messages to registered listeners. Each
listener runs independently with its own coroutine scope, ensuring non-blocking operation.
┌──────────────┐
│ DrLogger │
└──────┬───────┘
│
v
┌──────────────────┐ ┌─────────────────┐
│ DrLoggerFactory │──────>│ ILogListener │
└──────────────────┘ └─────────────────┘
│ │
├────────────────────────────┼──────────────┐
v v v
┌─────────────┐ ┌────────────────┐ ┌──────────┐
│ Console │ │ File Logger │ │ Logcat │
└─────────────┘ └────────────────┘ └──────────┘
// Set minimum log level globally
DrLogger.minLevel = DrLogLevel.INFO
// Enable/disable specific listeners
listener.enabled = true
DR-Logger uses a 512-element buffer for log messages. Messages are processed asynchronously to avoid blocking the calling thread.
ANDROID_HOME environment variableThis project is licensed under the MIT License - see the LICENSE file for details.
Built with:
For questions, issues, or feature requests:
| Platform | Target | Min Version |
|---|
| Android | androidTarget | API 24 (Android 7.0) |
| iOS | iosArm64, iosX64, iosSimulatorArm64 | iOS 12+ |
| JVM | jvm | Java 8+ |
| macOS | macosArm64, macosX64 | macOS 10.13+ |
| Linux | linuxX64, linuxArm64 | glibc 2.27+ |
| Windows | mingwX64 | Windows 7+ |
Surfaced from shared tags and platforms — no rankings paid for.