如何让 kotlin-logging (MicroUtils) 打印到 subclass 名称而不是抽象 class 名称?
How do I get kotlin-logging (MicroUtils) to print to subclass name instead of abstract class name?
我正在使用 kotlin-logging (https://github.com/MicroUtils/kotlin-logging),我希望我的记录器打印到 subclass 名称而不是抽象 class 名称。例如我有这些 class
// 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 是 subclass 名称)
您可能希望将记录器发送到摘要 class。
// 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
如果记录器在您的抽象 Class 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 的 class 都将根据其自己的 class 名称进行记录。
结果: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)
使用函数的 class 名称在内部调用 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
所以当我们在这里切分名称时:
https://github.com/MicroUtils/kotlin-logging/blob/master/src/jvmMain/kotlin/mu/internal/KLoggerNameResolver.kt#L18
结果只是 A
还值得注意的是,原始示例使用 A
是因为文件名为 A,而不是因为 class.
// 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
而如果函数是从 class
内部调用的
// 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
我正在使用 kotlin-logging (https://github.com/MicroUtils/kotlin-logging),我希望我的记录器打印到 subclass 名称而不是抽象 class 名称。例如我有这些 class
// 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 是 subclass 名称)
您可能希望将记录器发送到摘要 class。
// 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
如果记录器在您的抽象 Class 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 的 class 都将根据其自己的 class 名称进行记录。
结果: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)
使用函数的 class 名称在内部调用 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
所以当我们在这里切分名称时:
https://github.com/MicroUtils/kotlin-logging/blob/master/src/jvmMain/kotlin/mu/internal/KLoggerNameResolver.kt#L18
结果只是 A
还值得注意的是,原始示例使用 A
是因为文件名为 A,而不是因为 class.
// 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
而如果函数是从 class
内部调用的// 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