我正在使用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是子类名称)
您可能希望将记录器发送到抽象类。
// 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
如果记录器位于抽象的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。因此它在此名称解析器中找到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