2

我正在使用 kotlin-logging ( https://github.com/MicroUtils/kotlin-logging ),我希望我的记录器打印到子类名称而不是抽象类名称。示例我有这些课程

// in A.kt file:

import mu.KotlinLogging

private val logger = KotlinLogging.logger {}

abstract class A<T> {
    fun someMethod(item: T?) {
        logger.info("testing")
    }
}



fun main() {
    val b: A<String> = B()
    b.someMethod("123")
}




// in B.kt file

import mu.KotlinLogging

private val logger = KotlinLogging.logger {}

class B : A<String>() {
}

它打印:[main] INFO A - testing

但我希望它打印:[main] INFO B - testing (其中 B 是子类名称)

4

2 回答 2

3

您可能希望将记录器发送到抽象类。

// in A.kt file:

import mu.KotlinLogging

abstract class A<T>(private val logger: KLogger) {
    fun someMethod(item: T?) {
        logger.info("testing")
    }
}



fun main() {
    val b: A<String> = B()
    b.someMethod("123")
}




// in B.kt file

import mu.KotlinLogging

private val logger = KotlinLogging.logger {}

class B : A<String>(logger) {
}

结果: [main] INFO B - testing

于 2020-02-14T04:30:06.567 回答
2

如果记录器在您的抽象类 A 中,您可以使用 logger(name: String) 方法而不是 logger(func: () -> Unit) 方法,如下所示:

// in A.kt file

import mu.KotlinLogging

abstract class A<T> {
    private val logger = KotlinLogging.logger("${this::class.java.name}")

    fun someMethod(item: T?) {
        logger.info("testing")
    }
}

fun main() {
    val b: A<String> = B()
    b.someMethod("123")
}

// in B.kt file

class B : A<String>() {
}

这样任何扩展 A 的类都将根据其自己的类名进行记录。

结果:INFO B - testing

为什么?KotlinLogging 有两种方法,一种使用 ,logger(name: String)另一种使用logger(func: () -> Unit)在这里找到: https ://github.com/MicroUtils/kotlin-logging/blob/master/src/jvmMain/kotlin/mu/KotlinLogging.kt#L14-L16

内部使用函数的类名调用: logger(func: () -> Unit)https ://github.com/MicroUtils/kotlin-logging/blob/master/src/jvmMain/kotlin/mu/internal/KLoggerFactory.kt#L29-L30logger(name: String)

在您的情况下,A.kt 中的函数调用private val logger = KotlinLogging.logger {}来自 A.kt 内部,而不是该文件之外,因此它将始终来自 A。因此它A在此名称解析器中找到: https ://github.com/MicroUtils/ kotlin-logging/blob/master/src/jvmMain/kotlin/mu/internal/KLoggerNameResolver.kt#L15-L23

如果我们在这里使用这段代码:

import mu.KotlinLogging

private val funcJavaClass: String = {}.javaClass.name

abstract class A<T> {
    private val logger = KotlinLogging.logger("${this::class.java.name}")

    fun someMethod(item: T?) {
        logger.info("$funcJavaClass")
        logger.info("testing")
    }
}

结果是AKt$funcJavaClass$1这样,当我们在这里切片名称时: https ://github.com/MicroUtils/kotlin-logging/blob/master/src/jvmMain/kotlin/mu/internal/KLoggerNameResolver.kt#L18 结果很简单A

还值得注意的是,原始示例使用A是因为文件名是 A,而不是因为类。

// in R.kt

import mu.KotlinLogging

private val funcJavaClass: String = {}.javaClass.name

abstract class A<T> {
    private val logger = KotlinLogging.logger("${this::class.java.name}")

    fun someMethod(item: T?) {
        logger.info("$funcJavaClass")
        logger.info("testing")
    }
}

结果:RKt$funcJavaClass$1

而如果从类内部调用该函数

// in R.kt

import mu.KotlinLogging

abstract class A<T> {
    private val logger = KotlinLogging.logger("${this::class.java.name}")
    private val funcJavaClass: String = {}.javaClass.name

    fun someMethod(item: T?) {
        logger.info("$funcJavaClass")
        logger.info("testing")
    }
}

结果:A$funcJavaClass$1

于 2020-02-14T16:46:31.823 回答