Как заставить kotlin -logging (MicroUtils) печатать на имя подкласса вместо абстрактного имени класса? - PullRequest
2 голосов
/ 14 февраля 2020

Я использую 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] INFO B - тестирование (где B - имя подкласса)

Ответы [ 2 ]

3 голосов
/ 14 февраля 2020

Возможно, вы захотите отправить регистратор в абстрактный класс.

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

2 голосов
/ 14 февраля 2020

Если бы регистратор находился внутри вашего абстрактного класса A, вы могли бы использовать метод logger (name: String) вместо метода logger (fun c: () -> 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 в этом преобразователе имен: 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

...