From 37ea16d135a4f212b9d3cc2425d7ea9f3ef6d8e2 Mon Sep 17 00:00:00 2001 From: Severn Everett Date: Tue, 16 Apr 2024 13:57:54 +0200 Subject: [PATCH] Refined algorithm to determine the name of the hosting class of an anonymous logger --- .../internal/KLoggerNameResolver.kt | 29 ++++++++++++------- .../oshai/kotlinlogging/SimpleWasmJsTest.kt | 26 +++++++++++++---- 2 files changed, 40 insertions(+), 15 deletions(-) diff --git a/src/wasmJsMain/kotlin/io/github/oshai/kotlinlogging/internal/KLoggerNameResolver.kt b/src/wasmJsMain/kotlin/io/github/oshai/kotlinlogging/internal/KLoggerNameResolver.kt index e83bbfb1..ff6e37da 100644 --- a/src/wasmJsMain/kotlin/io/github/oshai/kotlinlogging/internal/KLoggerNameResolver.kt +++ b/src/wasmJsMain/kotlin/io/github/oshai/kotlinlogging/internal/KLoggerNameResolver.kt @@ -1,18 +1,27 @@ package io.github.oshai.kotlinlogging.internal +private const val NO_CLASS = "" + internal actual object KLoggerNameResolver { + private val kotlinLoggingRegex = Regex("\\.KotlinLogging\\.logger\\s") + private val topLevelPropertyRegex = Regex("") + private val classPropertyRegex = Regex("\\.(\\S+)\\.") internal actual fun name(func: () -> Unit): String { - var found = false - val exception = Exception() - for (line in exception.stackTraceToString().split("\n")) { - if (found) { - return line.substringBefore(".kt").substringAfterLast(".").substringAfterLast("/") - } - if (line.contains("at KotlinLogging")) { - found = true - } + val stackTrace = Exception().stackTraceToString().split("\n") + val invokingClassLine = stackTrace.indexOfFirst(kotlinLoggingRegex::containsMatchIn) + 1 + return if (invokingClassLine in 1 ..< stackTrace.size) { + getInvokingClass(stackTrace[invokingClassLine]) + } else { + NO_CLASS } - return "" + } + + private fun getInvokingClass(line: String): String { + return topLevelPropertyRegex.find(line)?.let { + it.groupValues[1].split(".").last() + } ?: classPropertyRegex.find(line)?.let { + it.groupValues[1].split(".").last() + } ?: NO_CLASS } } diff --git a/src/wasmJsTest/kotlin/io/github/oshai/kotlinlogging/SimpleWasmJsTest.kt b/src/wasmJsTest/kotlin/io/github/oshai/kotlinlogging/SimpleWasmJsTest.kt index 0e0e2a4c..a4629696 100644 --- a/src/wasmJsTest/kotlin/io/github/oshai/kotlinlogging/SimpleWasmJsTest.kt +++ b/src/wasmJsTest/kotlin/io/github/oshai/kotlinlogging/SimpleWasmJsTest.kt @@ -2,10 +2,12 @@ package io.github.oshai.kotlinlogging import kotlin.test.* -private val logger = KotlinLogging.logger("SimpleWasmJsTest") +private val namedLogger = KotlinLogging.logger("SimpleWasmJsTest") +private val anonymousFilePropLogger = KotlinLogging.logger { } class SimpleWasmJsTest { private lateinit var appender: SimpleAppender + private val anonymousClassPropLogger = KotlinLogging.logger { } @BeforeTest fun setup() { @@ -21,17 +23,31 @@ class SimpleWasmJsTest { @Test fun simpleWasmJsTest() { - assertEquals("SimpleWasmJsTest", logger.name) - logger.info { "info msg" } + assertEquals("SimpleWasmJsTest", namedLogger.name) + namedLogger.info { "info msg" } assertEquals("INFO: [SimpleWasmJsTest] info msg", appender.lastMessage) assertEquals("info", appender.lastLevel) } + @Test + fun anonymousFilePropWasmJsTest() { + assertEquals("SimpleWasmJsTest", anonymousFilePropLogger.name) + anonymousFilePropLogger.info { "info msg" } + assertEquals("INFO: [SimpleWasmJsTest] info msg", appender.lastMessage) + } + + @Test + fun anonymousClassPropWasmJsTest() { + assertEquals("SimpleWasmJsTest", anonymousClassPropLogger.name) + anonymousFilePropLogger.info { "info msg" } + assertEquals("INFO: [SimpleWasmJsTest] info msg", appender.lastMessage) + } + @Test fun offLevelWasmJsTest() { KotlinLoggingConfiguration.logLevel = Level.OFF - assertTrue(logger.isLoggingOff()) - logger.error { "error msg" } + assertTrue(namedLogger.isLoggingOff()) + namedLogger.error { "error msg" } assertEquals("NA", appender.lastMessage) assertEquals("NA", appender.lastLevel) }