
Lightweight logging API for libraries plus advanced engine for apps — tag-based routing with wildcard filters, independent importance tiers, and frequency controls (rate-limit, dedupe, sampling).
A comprehensive, flexible Kotlin Multiplatform logging library for JVM and Android.
LoggerWrapper is designed with two primary use cases in mind:
Logger interface so consumers can inject their own logging mechanism without pulling in heavy transitive dependencies.AdvancedLogger and AdvancedLoggerEngine to gain fine-grained control over log routing, frequency limiting (rate limiting, deduplication, sampling), and tag/importance-based filtering.This project follows the KMP Wizard 2026 layout:
shared — Kotlin Multiplatform library (commonMain + jvm + android)AndroidLogger) lives in shared/src/androidMain
Built with Kotlin 2.3.21, AGP 9.0.1, and the com.android.kotlin.multiplatform.library plugin.
v, d, i, w, e, wtf).LOW, MEDIUM, HIGH, CRITICAL) independent of log severity.RateLimitingFrequencyController: Limit max logs per tag in a time window.DeduplicatingFrequencyController: Suppress identical repeated messages.SamplingFrequencyController: Log only 1 in every N occurrences.ConsoleLogger: Standard output (common code).NoOpLogger: Silent logger for tests or defaults.CompositeLogger: Fan-out to multiple loggers.AndroidLogger: Direct android.util.Log wrapper (androidMain).dependencies {
implementation("com.example:LoggerWrapper:1.0.0")
}Gradle resolves the correct JVM or Android variant from the published KMP metadata.
For local development:
dependencies {
implementation(projects.shared)
}Expose the Logger interface in your library:
class MyLibrary(private val logger: Logger = NoOpLogger()) {
fun doWork() {
logger.i("Work started")
// ...
}
}Build an AdvancedLoggerEngine to control high-volume logging:
val engine = AdvancedLoggerEngineBuilder()
.addDelegate(ConsoleLogger())
.setGlobalMinLevel(LogLevel.INFO)
.setGlobalMinImportance(LogImportance.MEDIUM)
.addTagFilter(TagFilter("Network*", minLevel = LogLevel.VERBOSE, minImportance = LogImportance.LOW))
.setFrequencyController(
CompositeFrequencyController(
DeduplicatingFrequencyController(windowMillis = 5000),
RateLimitingFrequencyController(maxLogsPerWindow = 10, windowMillis = 1000)
)
)
.build()
engine.log(LogLevel.ERROR, tag = "NetworkHTTP", importance = LogImportance.HIGH, message = "Connection timeout")val logger = AndroidLogger(defaultTag = "MyApp")
logger.i("Ready")JVM (no Android SDK required):
./gradlew :shared:jvmTest
./gradlew :shared:publishJvmPublicationToMavenLocalFull build including Android requires the Android SDK (ANDROID_HOME or local.properties with sdk.dir):
./gradlew :shared:check
./gradlew :shared:publishToMavenLocalThis project is licensed under the Apache License 2.0.
A comprehensive, flexible Kotlin Multiplatform logging library for JVM and Android.
LoggerWrapper is designed with two primary use cases in mind:
Logger interface so consumers can inject their own logging mechanism without pulling in heavy transitive dependencies.AdvancedLogger and AdvancedLoggerEngine to gain fine-grained control over log routing, frequency limiting (rate limiting, deduplication, sampling), and tag/importance-based filtering.This project follows the KMP Wizard 2026 layout:
shared — Kotlin Multiplatform library (commonMain + jvm + android)AndroidLogger) lives in shared/src/androidMain
Built with Kotlin 2.3.21, AGP 9.0.1, and the com.android.kotlin.multiplatform.library plugin.
v, d, i, w, e, wtf).LOW, MEDIUM, HIGH, CRITICAL) independent of log severity.RateLimitingFrequencyController: Limit max logs per tag in a time window.DeduplicatingFrequencyController: Suppress identical repeated messages.SamplingFrequencyController: Log only 1 in every N occurrences.ConsoleLogger: Standard output (common code).NoOpLogger: Silent logger for tests or defaults.CompositeLogger: Fan-out to multiple loggers.AndroidLogger: Direct android.util.Log wrapper (androidMain).dependencies {
implementation("com.example:LoggerWrapper:1.0.0")
}Gradle resolves the correct JVM or Android variant from the published KMP metadata.
For local development:
dependencies {
implementation(projects.shared)
}Expose the Logger interface in your library:
class MyLibrary(private val logger: Logger = NoOpLogger()) {
fun doWork() {
logger.i("Work started")
// ...
}
}Build an AdvancedLoggerEngine to control high-volume logging:
val engine = AdvancedLoggerEngineBuilder()
.addDelegate(ConsoleLogger())
.setGlobalMinLevel(LogLevel.INFO)
.setGlobalMinImportance(LogImportance.MEDIUM)
.addTagFilter(TagFilter("Network*", minLevel = LogLevel.VERBOSE, minImportance = LogImportance.LOW))
.setFrequencyController(
CompositeFrequencyController(
DeduplicatingFrequencyController(windowMillis = 5000),
RateLimitingFrequencyController(maxLogsPerWindow = 10, windowMillis = 1000)
)
)
.build()
engine.log(LogLevel.ERROR, tag = "NetworkHTTP", importance = LogImportance.HIGH, message = "Connection timeout")val logger = AndroidLogger(defaultTag = "MyApp")
logger.i("Ready")JVM (no Android SDK required):
./gradlew :shared:jvmTest
./gradlew :shared:publishJvmPublicationToMavenLocalFull build including Android requires the Android SDK (ANDROID_HOME or local.properties with sdk.dir):
./gradlew :shared:check
./gradlew :shared:publishToMavenLocalThis project is licensed under the Apache License 2.0.