我如何让Kotlin日志记录(MicroUtils)打印到子类名称而不是抽象类名称?

问题描述 投票:1回答: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-测试

但是我希望它打印:[main]信息B-测试(其中B是子类名称)

kotlin logging slf4j kotlin-logging
2个回答
1
投票

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

// 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


1
投票

如果记录器位于抽象的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)使用函数的类名在内部调用logger(name: String)https://github.com/MicroUtils/kotlin-logging/blob/master/src/jvmMain/kotlin/mu/internal/KLoggerFactory.kt#L29-L30

在您的情况下,A.kt中的函数调用是private val logger = KotlinLogging.logger {}来自A.kt内部,永远不在该文件外部,因此它将始终来自A。因此它在此名称解析器中找到Ahttps://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

© www.soinside.com 2019 - 2024. All rights reserved.