什么是惯用的Kotlin方式来获取Logger?

时间:2016-06-08 09:10:46

标签: java log4j kotlin kotlin-logging

我想替换

private static final Logger log = Logger.getLogger(MyClass.class);

带有一些不那么冗长,更具惯用性的东西

class MyClass {
    companion object {
        val log = LoggerFactory.getLogger(MyClass::class.java)
    }

    fun usage() {
        log.debug("Success")
    }
}

奖励积分,因为不必在每个班级进行任务。

我试过了:

interface HasLogger {
    val log: Logger
        get() = LoggerFactory.getLogger(this.javaClass)
}

但这会导致每次使用的getLogger()调用(不可接受)也会返回子类型的记录器(而不是声明它的那个)。

2 个答案:

答案 0 :(得分:1)

您可以创建一个像

这样的实用工具方法
inline fun <reified T:Any> loggerFor() = LoggerFactory.getLogger(T::class.java)

只需像

一样使用它
class MyClass {
    companion object {
        val log = loggerFor<MyClass>()
    }

    fun usage() {
        log.debug("Success")
    }
}

或者你可以使用一个文件级私有记录器来节省一些打字,这似乎只是一个很好的解决方案,当你没有多个类,每个文件定义了自己的记录器时:

private val log = loggerFor<MyClass>()

class MyClass {
    fun usage() {
        log.debug("Success")
    }
}

答案 1 :(得分:1)

首先,您可以为记录器创建添加扩展功能。

inline fun <reified T : Any> getLogger() = LoggerFactory.getLogger(T::class.java)
fun <T : Any> T.getLogger() = LoggerFactory.getLogger(javaClass)

然后,您将能够使用以下代码创建记录器。

private val logger1 = getLogger<SomeClass>()
private val logger2 = getLogger()

其次,您可以定义一个提供记录器及其mixin实现的接口。

interface LoggerAware {
  val logger: Logger
}

class LoggerAwareMixin(containerClass: Class<*>) : LoggerAware {
  override val logger: Logger = LoggerFactory.getLogger(containerClass)
}

inline fun <reified T : Any> loggerAware() = LoggerAwareMixin(T::class.java)

此界面可以按以下方式使用。

class SomeClass : LoggerAware by loggerAware<SomeClass>() {
  // Now you can use a logger here.
}