What is the most convenient way to use SLF4J or other logging approaches with kotlin?
Usually the developer is busy with boilerplate code like
private val logger: Logger = LoggerFactory.getLogger(this::class.java)
in each and every class to get a proper logger?
What are the most convenient ways to unify/simplify this with Kotlin?
You can define an extension property on every type:
val <T : Any> T.logger: Logger
get() = LoggerFactory.getLogger(this::class.java)
use it as follows:
class X {
init {
logger.debug("init")
}
}
Here's a simple example which returns a lazily-initialized logger from a bound callable reference or a standard property. I prefer calling from a callable reference because the ::
denotes reflection (related to logging).
The class which provides the Lazy<Logger>
:
class LoggingProvider<T : Any>(val clazz: KClass<T>) {
operator fun provideDelegate(inst: Any?, property: KProperty<*>) =
lazy { LoggerFactory.getLogger(clazz.java) }
}
Inline functions to call them:
inline fun <reified T : Any> KCallable<T>.logger() =
LoggingProvider(T::class)
inline fun <reified T : Any> T.logger() =
LoggingProvider(T::class)
Here's an example of using them. The require
assertion in the initializer shows that the loggers share a reference:
class Foo {
val self: Foo = this
val logger by this.logger()
val callableLogger by this::self.logger()
init {
require(logger === callableLogger)
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With