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?
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)
}
}