Skip to content

Commit e9ec4a0

Browse files
authored
fix linux test (#542)
it appears that the tests were not running. when adding to the build they failed and had to fix. also seems that original implementation was too naive and do not work for cases of logger outside of class, so added implementation for it.
1 parent 98c4dc7 commit e9ec4a0

File tree

5 files changed

+120
-42
lines changed

5 files changed

+120
-42
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,4 @@ jobs:
6868
restore-keys: ${{ runner.os }}-gradle-
6969

7070
- name: Gradle Build
71-
run: ./gradlew clean build spotlessCheck --stacktrace
71+
run: ./gradlew clean build spotlessCheck --stacktrace --info

build.gradle.kts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,9 @@ kotlin {
241241
getByName("${it.targetName}Main") {
242242
dependsOn(linuxMain)
243243
}
244+
getByName("${it.targetName}Test") {
245+
dependsOn(nativeTest)
246+
}
244247
}
245248
darwinTargets.forEach {
246249
getByName("${it.targetName}Main") {
Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,52 @@
11
package io.github.oshai.kotlinlogging.internal
22

3+
import kotlin.experimental.ExperimentalNativeApi
4+
35
internal actual object KLoggerNameResolver {
46

5-
internal actual fun name(func: () -> Unit): String = func::class.qualifiedName ?: ""
7+
private fun removeKtSuffix(fullyQualifiedName: String): String {
8+
return if (fullyQualifiedName.endsWith("Kt")) {
9+
fullyQualifiedName.substring(0, fullyQualifiedName.length - 2)
10+
} else {
11+
fullyQualifiedName
12+
}
13+
}
14+
15+
@OptIn(ExperimentalNativeApi::class)
16+
internal actual fun name(func: () -> Unit): String {
17+
// Primary method: For loggers in classes, reflection returns the FQ name.
18+
val nameFromReflection = func::class.qualifiedName?.substringBeforeLast(".<anonymous>")
19+
if (!nameFromReflection.isNullOrBlank()) {
20+
return nameFromReflection
21+
}
22+
23+
// Fallback for top-level loggers: Parse the stack trace string array.
24+
val stackTrace: Array<String> = Throwable().getStackTrace()
25+
26+
// START: Diagnostic code
27+
// println("--- KOTLIN-LOGGING DIAGNOSTIC: STACK TRACE ---")
28+
// stackTrace.forEach { println(it) }
29+
// println("--- END DIAGNOSTIC ---")
30+
// END: Diagnostic code
31+
32+
// Find the first frame outside of the logging framework's internal machinery.
33+
val callerFrame =
34+
stackTrace.firstOrNull {
35+
!it.contains("kfun:kotlin.Throwable") &&
36+
!it.contains("io.github.oshai.kotlinlogging.internal") &&
37+
!it.contains("io.github.oshai.kotlinlogging.KotlinLogging") &&
38+
!it.contains("kfun:io.github.oshai.kotlinlogging.\$init_global#internal") &&
39+
!it.contains("CallInitGlobalPossiblyLock") &&
40+
!it.contains("kfun:io.github.oshai.kotlinlogging.<get-logger>#internal")
41+
}
42+
43+
if (callerFrame != null) {
44+
val regex = Regex("""kfun:([^#(<]+)""")
45+
val fqName = regex.find(callerFrame)?.groupValues?.get(1)?.trim()
46+
if (fqName != null) {
47+
return removeKtSuffix(fqName)
48+
}
49+
}
50+
return "UnknownLogger"
51+
}
652
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package io.github.oshai.kotlinlogging
2+
3+
import kotlin.test.Test
4+
import kotlin.test.assertEquals
5+
6+
class ClassLoggerNativeTest {
7+
8+
private val logger = KotlinLogging.logger {}
9+
10+
@Test
11+
fun loggerNameIsCorrectlyInferredFromClass() {
12+
println(
13+
"Asserting logger name from class: Expected 'io.github.oshai.kotlinlogging.ClassLoggerNativeTest', was '${logger.name}'"
14+
)
15+
assertEquals("io.github.oshai.kotlinlogging.ClassLoggerNativeTest", logger.name)
16+
}
17+
}

src/nativeTest/kotlin/io/github/oshai/kotlinlogging/SimpleNativeTest.kt

Lines changed: 52 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -21,61 +21,73 @@ class SimpleNativeTest {
2121

2222
@Test
2323
fun simpleNativeTest() {
24-
assertEquals("SimpleNativeTest", logger.name)
24+
println("Asserting logger name: Expected 'SimpleNativeTest', was '${logger.name}'")
25+
assertEquals(
26+
"io.github.oshai.kotlinlogging.SimpleNativeTest",
27+
logger.name,
28+
"Expected logger name to be 'io.github.oshai.kotlinlogging.SimpleNativeTest', was '${logger.name}'",
29+
)
2530
logger.info { "info msg" }
26-
assertEquals("INFO: [SimpleNativeTest] info msg", appender.lastMessage)
27-
assertEquals("info", appender.lastLevel)
28-
assertEquals("info", appender.lastLoggerName)
31+
println("Asserting last message: Expected 'info msg', was '${appender.lastMessage}'")
32+
assertEquals(
33+
"info msg",
34+
appender.lastMessage,
35+
"Expected last message to be 'info msg', was '${appender.lastMessage}'",
36+
)
37+
println("Asserting last level: Expected 'info', was '${appender.lastLevel}'")
38+
assertEquals(
39+
"info",
40+
appender.lastLevel,
41+
"Expected last level to be 'info', was '${appender.lastLevel}'",
42+
)
43+
println(
44+
"Asserting last logger name: Expected 'io.github.oshai.kotlinlogging.SimpleNativeTest', was '${appender.lastLoggerName}'"
45+
)
46+
assertEquals(
47+
"io.github.oshai.kotlinlogging.SimpleNativeTest",
48+
appender.lastLoggerName,
49+
"Expected last logger name to be 'io.github.oshai.kotlinlogging.SimpleNativeTest', was '${appender.lastLoggerName}'",
50+
)
2951
}
3052

3153
@Test
3254
fun offLevelNativeTest() {
3355
KotlinLoggingConfiguration.logLevel = Level.OFF
34-
assertTrue(logger.isLoggingOff)
56+
val isLoggingOff = logger.isLoggingOff()
57+
println("Asserting logging is off: Expected true, was '$isLoggingOff'")
58+
assertTrue(isLoggingOff, "Expected logging to be off, was '$isLoggingOff'")
3559
logger.error { "error msg" }
36-
assertEquals("NA", appender.lastMessage)
37-
assertEquals("NA", appender.lastLevel)
38-
assertEquals("NA", appender.lastLoggerName)
60+
println("Asserting last message is 'NA': Expected 'NA', was '${appender.lastMessage}'")
61+
assertEquals(
62+
"NA",
63+
appender.lastMessage,
64+
"Expected last message to be 'NA' when logging is off, was '${appender.lastMessage}'",
65+
)
66+
println("Asserting last level is 'NA': Expected 'NA', was '${appender.lastLevel}'")
67+
assertEquals(
68+
"NA",
69+
appender.lastLevel,
70+
"Expected last level to be 'NA' when logging is off, was '${appender.lastLevel}'",
71+
)
72+
println("Asserting last logger name is 'NA': Expected 'NA', was '${appender.lastLoggerName}'")
73+
assertEquals(
74+
"NA",
75+
appender.lastLoggerName,
76+
"Expected last logger name to be 'NA' when logging is off, was '${appender.lastLoggerName}'",
77+
)
3978
}
4079

4180
private fun createAppender(): SimpleAppender = SimpleAppender()
4281

4382
class SimpleAppender : Appender {
44-
var lastMessage: String = "NA"
83+
var lastMessage: String? = "NA"
4584
var lastLevel: String = "NA"
4685
var lastLoggerName: String = "NA"
4786

48-
override fun trace(loggerName: String, message: String) {
49-
lastMessage = message
50-
lastLevel = "trace"
51-
lastLoggerName = loggerName
87+
override fun log(loggingEvent: KLoggingEvent) {
88+
lastMessage = loggingEvent.message
89+
lastLevel = loggingEvent.level.name.lowercase()
90+
lastLoggerName = loggingEvent.loggerName
5291
}
53-
54-
override fun debug(loggerName: String, message: String) {
55-
lastMessage = message
56-
lastLevel = "debug"
57-
lastLoggerName = loggerName
58-
}
59-
60-
override fun info(loggerName: String, message: String) {
61-
lastMessage = message
62-
lastLevel = "info"
63-
lastLoggerName = loggerName
64-
}
65-
66-
override fun warn(loggerName: String, message: String) {
67-
lastMessage = message
68-
lastLevel = "warn"
69-
lastLoggerName = loggerName
70-
}
71-
72-
override fun error(loggerName: String, message: String) {
73-
lastMessage = message
74-
lastLevel = "error"
75-
lastLoggerName = loggerName
76-
}
77-
78-
override val includePrefix: Boolean
79-
get() = true
8092
}
8193
}

0 commit comments

Comments
 (0)