使用logback(slf4j)实现Kotlin扩展日志函数

5

我创建了一个用于记录日志的扩展函数:

import org.slf4j.LoggerFactory

fun Any.log(msg: String) {
    LoggerFactory.getLogger(javaClass.name).debug(msg)
}

但我不确定在调用LoggerFactory.getLogger方法时会不会初始化,因为它会调用getILoggerFactory方法。

也许已经有人做过这样的事情并且可以保证它不会有任何内存泄漏 :) ?

目前我使用传统的方式(在类中声明logger字段):

companion object {
    private val logger = LoggerFactory.getLogger(LoggerTest::class.java.name)
}

但是像这样的一个简单的单元测试:

@Test
fun testLogger() {
    val start = System.currentTimeMillis()
    for (i in 0..999) {
        log("i=" + i)
    }
    val end = System.currentTimeMillis()
    val time = end - start
    println("*** TIME=" + time.toDouble() / 1000 + " sec")
}

显示的结果与旧式选项相同:

@Test
fun testLogger() {
    val start = System.currentTimeMillis()
    for (i in 0..999) {
        logger.debug("i=" + i)
    }
    val end = System.currentTimeMillis()
    val time = end - start
    println("*** TIME=" + time.toDouble() / 1000 + " sec")
}

companion object {
    private val logger = LoggerFactory.getLogger(LoggerTest::class.java.name)
}

~ *** TIME=0.02 sec

I'm using:

org.slf4j - 1.7.25
ch.qos.logback - 1.2.3

3
看起来 LoggerFactory.getLogger(...) 没有每次都构建一个新的记录器(logger),而是能够重复使用它们,但正如这个答案中所说,这些调用并不是免费的,所以你不应该这样做。 - hotkey
也许有另一种选项可以使用logback来创建Kotlin函数扩展? - user2870934
如果您使用 Any.foo() { do sth with javaClass } 并像这样调用它 String.foo(),那么 javaClass 应该是 StringAny(我不确定),但绝对不是调用类。然而,与老式方法相比,这并不能给您相同的结果。 - msrd0
实际上,我可能会选择 interface HasLogger { val logger : Logger } 并定义 HasLogger.log()。尽管这仍然需要每个实例一个记录器,而不是每个类一个记录器。 - msrd0
1个回答

3

对于日志记录,我可以推荐另一种解决方案。

首先,添加接口ILogging和类LoggingImpl:

interface ILogging {
    val log: Logger
}

class LoggingImp(loggerImpl: Logger) : ILogging {
    override val log: Logger = loggerImpl

    companion object {
        operator inline fun <reified T> invoke(): LoggingImp {
            return LoggingImp(LoggerFactory.getLogger(T::class.java))
        }
    }
}

现在,你可以使用Kotlin委托将记录器添加到任何类中:

class TestClass : ILogging by LoggingImp<TestClass>() {
    fun test() {
        log.info("test")
    }
}

在创建父对象时会创建日志记录器。以下是使用示例:

fun main(args: Array<String>) {
    val testClass = TestClass()

    testClass.test()
}

希望这能帮到你。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接