Apa cara idiomatis Kotlin untuk mendapatkan Logger? [duplikat]

Aku sedang mencari penggantinya

private static final Logger log = Logger.getLogger(MyClass.class);

dengan sesuatu yang tidak terlalu bertele-tele dan lebih idiomatis

class MyClass {
    companion object {
        val log = LoggerFactory.getLogger(MyClass::class.java)
    }

    fun usage() {
        log.debug("Success")
    }
}

Poin bonus karena tidak harus melakukan delcare di setiap kelas.

Saya mencoba:

interface HasLogger {
    val log: Logger
        get() = LoggerFactory.getLogger(this.javaClass)
}

Tapi ini menghasilkan panggilan getLogger() untuk setiap penggunaan (tidak dapat diterima) juga mengembalikan logger untuk subtipe (bukan subtipe yang dideklarasikan).


person atok    schedule 08.06.2016    source sumber
comment
lihat lib ini: github.com/MicroUtils/kotlin.logging   -  person oshai    schedule 14.07.2016


Jawaban (2)


Anda dapat membuat metode utilitas seperti

inline fun <reified T:Any> loggerFor() = LoggerFactory.getLogger(T::class.java)

Dan cukup gunakan seperti itu

class MyClass {
    companion object {
        val log = loggerFor<MyClass>()
    }

    fun usage() {
        log.debug("Success")
    }
}

Alternatifnya, Anda dapat menggunakan logger pribadi tingkat file yang menghemat pengetikan Anda, yang tampaknya hanya menjadi solusi yang baik ketika Anda tidak memiliki banyak kelas dengan loggernya sendiri yang ditentukan per file:

private val log = loggerFor<MyClass>()

class MyClass {
    fun usage() {
        log.debug("Success")
    }
}
person M Platvoet    schedule 08.06.2016
comment
Ini masih sedikit untuk seleraku. Tapi sepertinya itu bisa berfungsi tanpa ‹MyClass› menggunakan LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()) - person atok; 08.06.2016

Pertama, Anda dapat menambahkan fungsi ekstensi untuk pembuatan logger.

inline fun <reified T : Any> getLogger() = LoggerFactory.getLogger(T::class.java)
fun <T : Any> T.getLogger() = LoggerFactory.getLogger(javaClass)

Kemudian Anda akan dapat membuat logger menggunakan kode berikut.

private val logger1 = getLogger<SomeClass>()
private val logger2 = getLogger()

Kedua, Anda dapat menentukan antarmuka yang menyediakan logger dan implementasi mixinnya.

interface LoggerAware {
  val logger: Logger
}

class LoggerAwareMixin(containerClass: Class<*>) : LoggerAware {
  override val logger: Logger = LoggerFactory.getLogger(containerClass)
}

inline fun <reified T : Any> loggerAware() = LoggerAwareMixin(T::class.java)

Antarmuka ini dapat digunakan dengan cara berikut.

class SomeClass : LoggerAware by loggerAware<SomeClass>() {
  // Now you can use a logger here.
}
person Michael    schedule 08.06.2016
comment
Wow! Itu keren! Anda bahkan dapat mengganti T yang direifikasi dengan MethodHandles.lookup().lookupClass() dan mendapatkan hasil yang sama tanpa mengeja SomeClass untuk kedua kalinya: inline fun loggerAware() = HasLoggerMixin(MethodHandles.lookup().lookupClass()) - person atok; 08.06.2016
comment
@atok Yap, sepertinya bisa. - person Michael; 08.06.2016
comment
Terima kasih. Saya pikir Anda harus memposting ini di pertanyaan ini: stackoverflow.com/questions/34416869/ karena lebih baik dari hasilnya - person atok; 08.06.2016