I'm trying to create an extension for KLogger/Logger which is an extension for slf4j's logger in order to better handle structured log messages. Could someone explain what's wrong with my code and how to fix it or work around it without passing my logger object? My extension is never called.
Below you may see the minimalistic build.gradle + snippet of code:
App.kt:
import mu.KLogger
import mu.KotlinLogging
private val log = KotlinLogging.logger {}
fun main() {
log.info("log message",
"key1" to "value1",
"key2" to "value2"
)
}
fun KLogger.info(message: String, vararg keyValues: Pair<String, Any?>) {
log.info("log extension")
info(message)
}
build.gradle.kts:
plugins {
kotlin("jvm") version "1.3.72"
}
group = "rg"
version = "1.0"
java.sourceCompatibility = JavaVersion.VERSION_11
repositories {
mavenCentral()
}
dependencies {
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
implementation("ch.qos.logback:logback-classic:1.2.3")
implementation("io.github.microutils:kotlin-logging:1.7.6")
}
Update: I end up with dropping extension idea and convert the existing code to a delegate.
fun structuredLogger(func: () -> Unit): StructuredLogger = StructuredLogger(func)
class StructuredLogger(func: () -> Unit, private val log: KLogger = KotlinLogging.logger(func)) : KLogger by log {
fun info(msg: String?, vararg keyValues: Pair<LoggingKey, Any?>) {
log.info(marker(*keyValues), msg)
}
// (...)
}
Logger
has a function with the signature info(message: String, vararg arguments: Any)
(as converted to Kotlin). Although yourvararg
is for Pairs, that is just an ambiguous overload of Any. Extension functions cannot override non-extension functions and will simply be ignored if they do. You will have to change your function name or parameters.