From 39ec588f730e5b4dc0ee96115754ccb68f0893d3 Mon Sep 17 00:00:00 2001 From: Conrad Kramer Date: Fri, 8 Apr 2022 11:30:33 -0700 Subject: [PATCH 1/3] Rename MarkerLinux to MarkerNative This implementation is shared across all native implementations --- src/nativeMain/kotlin/mu/KMarkerFactory.kt | 4 ++-- .../kotlin/mu/internal/{MarkerLinux.kt => MarkerNative.kt} | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) rename src/nativeMain/kotlin/mu/internal/{MarkerLinux.kt => MarkerNative.kt} (57%) diff --git a/src/nativeMain/kotlin/mu/KMarkerFactory.kt b/src/nativeMain/kotlin/mu/KMarkerFactory.kt index 1c2212d7..3e92f599 100644 --- a/src/nativeMain/kotlin/mu/KMarkerFactory.kt +++ b/src/nativeMain/kotlin/mu/KMarkerFactory.kt @@ -1,8 +1,8 @@ package mu -import mu.internal.MarkerLinux +import mu.internal.MarkerNative public actual object KMarkerFactory { - public actual fun getMarker(name: String): Marker = MarkerLinux(name) + public actual fun getMarker(name: String): Marker = MarkerNative(name) } diff --git a/src/nativeMain/kotlin/mu/internal/MarkerLinux.kt b/src/nativeMain/kotlin/mu/internal/MarkerNative.kt similarity index 57% rename from src/nativeMain/kotlin/mu/internal/MarkerLinux.kt rename to src/nativeMain/kotlin/mu/internal/MarkerNative.kt index 0825812c..5f06e1f5 100644 --- a/src/nativeMain/kotlin/mu/internal/MarkerLinux.kt +++ b/src/nativeMain/kotlin/mu/internal/MarkerNative.kt @@ -2,7 +2,7 @@ package mu.internal import mu.Marker -internal class MarkerLinux(private val name: String) : Marker { +internal class MarkerNative(private val name: String) : Marker { override fun getName(): String = this.name } From 8b0fae17ec4693c53981e66c42539b6d066d7435 Mon Sep 17 00:00:00 2001 From: Conrad Kramer Date: Fri, 8 Apr 2022 11:35:04 -0700 Subject: [PATCH 2/3] Add loggerName to the Appender interface On Darwin platforms using os_log, a separate logger can be created for each differently named logger. The Appender, which directs the text of the log message, needs to know which logger to direct it to. --- src/nativeMain/kotlin/mu/Appender.kt | 10 +++++----- .../kotlin/mu/ConsoleOutputAppender.kt | 10 +++++----- src/nativeMain/kotlin/mu/Formatter.kt | 8 ++++---- .../kotlin/mu/internal/KLoggerLinux.kt | 16 ++++++++-------- 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/nativeMain/kotlin/mu/Appender.kt b/src/nativeMain/kotlin/mu/Appender.kt index 02303544..1f169aa6 100644 --- a/src/nativeMain/kotlin/mu/Appender.kt +++ b/src/nativeMain/kotlin/mu/Appender.kt @@ -1,9 +1,9 @@ package mu public interface Appender { - public fun trace(message: Any?) - public fun debug(message: Any?) - public fun info(message: Any?) - public fun warn(message: Any?) - public fun error(message: Any?) + public fun trace(loggerName: String, message: String) + public fun debug(loggerName: String, message: String) + public fun info(loggerName: String, message: String) + public fun warn(loggerName: String, message: String) + public fun error(loggerName: String, message: String) } diff --git a/src/nativeMain/kotlin/mu/ConsoleOutputAppender.kt b/src/nativeMain/kotlin/mu/ConsoleOutputAppender.kt index f87db080..e0d19cae 100644 --- a/src/nativeMain/kotlin/mu/ConsoleOutputAppender.kt +++ b/src/nativeMain/kotlin/mu/ConsoleOutputAppender.kt @@ -4,12 +4,12 @@ import platform.posix.fprintf import platform.posix.stderr public object ConsoleOutputAppender : Appender { - public override fun trace(message: Any?): Unit = println(message) - public override fun debug(message: Any?): Unit = println(message) - public override fun info(message: Any?): Unit = println(message) - public override fun warn(message: Any?): Unit = println(message) + public override fun trace(loggerName: String, message: String): Unit = println(message) + public override fun debug(loggerName: String, message: String): Unit = println(message) + public override fun info(loggerName: String, message: String): Unit = println(message) + public override fun warn(loggerName: String, message: String): Unit = println(message) - override fun error(message: Any?) { + override fun error(loggerName: String, message: String) { fprintf(stderr, "$message\n") } } diff --git a/src/nativeMain/kotlin/mu/Formatter.kt b/src/nativeMain/kotlin/mu/Formatter.kt index 83c32c8a..440caa3a 100644 --- a/src/nativeMain/kotlin/mu/Formatter.kt +++ b/src/nativeMain/kotlin/mu/Formatter.kt @@ -1,14 +1,14 @@ package mu public interface Formatter { - public fun formatMessage(level: KotlinLoggingLevel, loggerName: String, msg: () -> Any?): Any? - public fun formatMessage(level: KotlinLoggingLevel, loggerName: String, t: Throwable?, msg: () -> Any?): Any? - public fun formatMessage(level: KotlinLoggingLevel, loggerName: String, marker: Marker?, msg: () -> Any?): Any? + public fun formatMessage(level: KotlinLoggingLevel, loggerName: String, msg: () -> Any?): String + public fun formatMessage(level: KotlinLoggingLevel, loggerName: String, t: Throwable?, msg: () -> Any?): String + public fun formatMessage(level: KotlinLoggingLevel, loggerName: String, marker: Marker?, msg: () -> Any?): String public fun formatMessage( level: KotlinLoggingLevel, loggerName: String, marker: Marker?, t: Throwable?, msg: () -> Any? - ): Any? + ): String } diff --git a/src/nativeMain/kotlin/mu/internal/KLoggerLinux.kt b/src/nativeMain/kotlin/mu/internal/KLoggerLinux.kt index 6c0677b4..b43b1df3 100644 --- a/src/nativeMain/kotlin/mu/internal/KLoggerLinux.kt +++ b/src/nativeMain/kotlin/mu/internal/KLoggerLinux.kt @@ -57,21 +57,21 @@ internal class KLoggerLinux( override fun error(marker: Marker?, t: Throwable?, msg: () -> Any?) = ERROR.logIfEnabled(marker, msg, t, appender::error) - private fun KotlinLoggingLevel.logIfEnabled(msg: () -> Any?, logFunction: (Any?) -> Unit) { + private fun KotlinLoggingLevel.logIfEnabled(msg: () -> Any?, logFunction: (String, String) -> Unit) { if (isLoggingEnabled()) { - logFunction(formatter.formatMessage(this, loggerName, msg)) + logFunction(loggerName, formatter.formatMessage(this, loggerName, msg)) } } - private fun KotlinLoggingLevel.logIfEnabled(msg: () -> Any?, t: Throwable?, logFunction: (Any?) -> Unit) { + private fun KotlinLoggingLevel.logIfEnabled(msg: () -> Any?, t: Throwable?, logFunction: (String, String) -> Unit) { if (isLoggingEnabled()) { - logFunction(formatter.formatMessage(this, loggerName, t, msg)) + logFunction(loggerName, formatter.formatMessage(this, loggerName, t, msg)) } } - private fun KotlinLoggingLevel.logIfEnabled(marker: Marker?, msg: () -> Any?, logFunction: (Any?) -> Unit) { + private fun KotlinLoggingLevel.logIfEnabled(marker: Marker?, msg: () -> Any?, logFunction: (String, String) -> Unit) { if (isLoggingEnabled()) { - logFunction(formatter.formatMessage(this, loggerName, marker, msg)) + logFunction(loggerName, formatter.formatMessage(this, loggerName, marker, msg)) } } @@ -79,10 +79,10 @@ internal class KLoggerLinux( marker: Marker?, msg: () -> Any?, t: Throwable?, - logFunction: (Any?) -> Unit + logFunction: (String, String) -> Unit ) { if (isLoggingEnabled()) { - logFunction(formatter.formatMessage(this, loggerName, marker, t, msg)) + logFunction(loggerName, formatter.formatMessage(this, loggerName, marker, t, msg)) } } From 0707b5bf5e085e379e38ab84fe996edffd2439f7 Mon Sep 17 00:00:00 2001 From: Conrad Kramer Date: Fri, 8 Apr 2022 12:14:57 -0700 Subject: [PATCH 3/3] Add OSLogAppender to append logs to os_log on Darwin platforms --- build.gradle.kts | 36 +++++++++++--- .../kotlin/mu/KotlinLoggingConfiguration.kt | 3 ++ src/darwinMain/kotlin/mu/OSLogAppender.kt | 49 +++++++++++++++++++ .../kotlin/mu/OSLogSubsystemAppender.kt | 28 +++++++++++ .../kotlin/mu/KotlinLoggingConfiguration.kt | 3 ++ src/nativeMain/kotlin/mu/Appender.kt | 2 + .../kotlin/mu/ConsoleOutputAppender.kt | 1 + .../kotlin/mu/DefaultMessageFormatter.kt | 23 ++++++--- src/nativeMain/kotlin/mu/Formatter.kt | 7 +-- .../kotlin/mu/KotlinLoggingConfiguration.kt | 4 +- .../kotlin/mu/internal/KLoggerLinux.kt | 8 +-- 11 files changed, 142 insertions(+), 22 deletions(-) create mode 100644 src/darwinMain/kotlin/mu/KotlinLoggingConfiguration.kt create mode 100644 src/darwinMain/kotlin/mu/OSLogAppender.kt create mode 100644 src/darwinMain/kotlin/mu/OSLogSubsystemAppender.kt create mode 100644 src/linuxMain/kotlin/mu/KotlinLoggingConfiguration.kt diff --git a/build.gradle.kts b/build.gradle.kts index 29d8d2bf..6d7a6f81 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -51,9 +51,24 @@ kotlin { nodejs() } - linuxX64("linuxX64") - macosX64("macosX64") - mingwX64("mingwX64") + val linuxTargets = listOf( + linuxArm64(), + linuxX64(), + mingwX64() + ) + val darwinTargets = listOf( + macosArm64(), + macosX64(), + iosArm64(), + iosSimulatorArm64(), + iosX64(), + watchosArm64(), + watchosSimulatorArm64(), + watchosX64(), + tvosArm64(), + tvosSimulatorArm64(), + tvosX64() + ) sourceSets { val commonMain by getting {} @@ -88,14 +103,21 @@ kotlin { val nativeMain by creating { dependsOn(commonMain) } - val linuxX64Main by getting { + val linuxMain by creating { dependsOn(nativeMain) } - val mingwX64Main by getting { + val darwinMain by creating { dependsOn(nativeMain) } - val macosX64Main by getting { - dependsOn(nativeMain) + linuxTargets.forEach { + getByName("${it.targetName}Main") { + dependsOn(linuxMain) + } + } + darwinTargets.forEach { + getByName("${it.targetName}Main") { + dependsOn(darwinMain) + } } } } diff --git a/src/darwinMain/kotlin/mu/KotlinLoggingConfiguration.kt b/src/darwinMain/kotlin/mu/KotlinLoggingConfiguration.kt new file mode 100644 index 00000000..45053359 --- /dev/null +++ b/src/darwinMain/kotlin/mu/KotlinLoggingConfiguration.kt @@ -0,0 +1,3 @@ +package mu + +public actual val DefaultAppender: Appender = OSLogAppender() diff --git a/src/darwinMain/kotlin/mu/OSLogAppender.kt b/src/darwinMain/kotlin/mu/OSLogAppender.kt new file mode 100644 index 00000000..84d09bb6 --- /dev/null +++ b/src/darwinMain/kotlin/mu/OSLogAppender.kt @@ -0,0 +1,49 @@ +package mu + +import kotlinx.cinterop.ptr +import platform.darwin.OS_LOG_DEFAULT +import platform.darwin.OS_LOG_TYPE_DEBUG +import platform.darwin.OS_LOG_TYPE_DEFAULT +import platform.darwin.OS_LOG_TYPE_ERROR +import platform.darwin.OS_LOG_TYPE_INFO +import platform.darwin.__dso_handle +import platform.darwin._os_log_internal +import platform.darwin.os_log_t +import platform.darwin.os_log_type_enabled +import platform.darwin.os_log_type_t +import kotlin.native.concurrent.AtomicReference + +public open class OSLogAppender: Appender { + override val includePrefix: Boolean = true + + protected open fun logger(loggerName: String): os_log_t { + return OS_LOG_DEFAULT + } + + private fun log(level: os_log_type_t, loggerName: String, message: String) { + val logger = logger(loggerName) + if (os_log_type_enabled(logger, level)) { + _os_log_internal(__dso_handle.ptr, logger, level, message) + } + } + + override fun trace(loggerName: String, message: String) { + log(OS_LOG_TYPE_DEBUG, loggerName, message) + } + + override fun debug(loggerName: String, message: String) { + log(OS_LOG_TYPE_DEBUG, loggerName, message) + } + + override fun info(loggerName: String, message: String) { + log(OS_LOG_TYPE_INFO, loggerName, message) + } + + override fun warn(loggerName: String, message: String) { + log(OS_LOG_TYPE_DEFAULT, loggerName, message) + } + + override fun error(loggerName: String, message: String) { + log(OS_LOG_TYPE_ERROR, loggerName, message) + } +} diff --git a/src/darwinMain/kotlin/mu/OSLogSubsystemAppender.kt b/src/darwinMain/kotlin/mu/OSLogSubsystemAppender.kt new file mode 100644 index 00000000..edff0cfc --- /dev/null +++ b/src/darwinMain/kotlin/mu/OSLogSubsystemAppender.kt @@ -0,0 +1,28 @@ +package mu + +import platform.darwin.os_log_create +import platform.darwin.os_log_t +import kotlin.native.concurrent.AtomicReference + +public class OSLogSubsystemAppender(public val subsystem: String) : OSLogAppender() { + override val includePrefix: Boolean = false + + private val logs: AtomicReference> = AtomicReference(mapOf()) + + override fun logger(loggerName: String): os_log_t { + var logger: os_log_t + do { + val existing = logs.value + logger = existing[loggerName] + if (logger != null) { + return logger + } + + val updated = existing.toMutableMap() + logger = os_log_create(subsystem, loggerName) + updated[loggerName] = logger + } while (!logs.compareAndSet(existing, updated)) + + return logger + } +} diff --git a/src/linuxMain/kotlin/mu/KotlinLoggingConfiguration.kt b/src/linuxMain/kotlin/mu/KotlinLoggingConfiguration.kt new file mode 100644 index 00000000..7f23ccd0 --- /dev/null +++ b/src/linuxMain/kotlin/mu/KotlinLoggingConfiguration.kt @@ -0,0 +1,3 @@ +package mu + +public actual val DefaultAppender: Appender = ConsoleOutputAppender diff --git a/src/nativeMain/kotlin/mu/Appender.kt b/src/nativeMain/kotlin/mu/Appender.kt index 1f169aa6..04c84395 100644 --- a/src/nativeMain/kotlin/mu/Appender.kt +++ b/src/nativeMain/kotlin/mu/Appender.kt @@ -1,6 +1,8 @@ package mu public interface Appender { + public val includePrefix: Boolean + public fun trace(loggerName: String, message: String) public fun debug(loggerName: String, message: String) public fun info(loggerName: String, message: String) diff --git a/src/nativeMain/kotlin/mu/ConsoleOutputAppender.kt b/src/nativeMain/kotlin/mu/ConsoleOutputAppender.kt index e0d19cae..065d3c04 100644 --- a/src/nativeMain/kotlin/mu/ConsoleOutputAppender.kt +++ b/src/nativeMain/kotlin/mu/ConsoleOutputAppender.kt @@ -4,6 +4,7 @@ import platform.posix.fprintf import platform.posix.stderr public object ConsoleOutputAppender : Appender { + override val includePrefix: Boolean = true public override fun trace(loggerName: String, message: String): Unit = println(message) public override fun debug(loggerName: String, message: String): Unit = println(message) public override fun info(loggerName: String, message: String): Unit = println(message) diff --git a/src/nativeMain/kotlin/mu/DefaultMessageFormatter.kt b/src/nativeMain/kotlin/mu/DefaultMessageFormatter.kt index bbffc36b..6d16ef5e 100644 --- a/src/nativeMain/kotlin/mu/DefaultMessageFormatter.kt +++ b/src/nativeMain/kotlin/mu/DefaultMessageFormatter.kt @@ -3,23 +3,32 @@ package mu import mu.internal.toStringSafe public object DefaultMessageFormatter : Formatter { - public override fun formatMessage(level: KotlinLoggingLevel, loggerName: String, msg: () -> Any?): String = - "${level.name}: [$loggerName] ${msg.toStringSafe()}" + public override fun formatMessage(includePrefix: Boolean, level: KotlinLoggingLevel, loggerName: String, msg: () -> Any?): String = + "${prefix(includePrefix, level, loggerName)}${msg.toStringSafe()}" - public override fun formatMessage(level: KotlinLoggingLevel, loggerName: String, t: Throwable?, msg: () -> Any?): String = - "${level.name}: [$loggerName] ${msg.toStringSafe()}${t.throwableToString()}" + public override fun formatMessage(includePrefix: Boolean, level: KotlinLoggingLevel, loggerName: String, t: Throwable?, msg: () -> Any?): String = + "${prefix(includePrefix, level, loggerName)}${msg.toStringSafe()}${t.throwableToString()}" - public override fun formatMessage(level: KotlinLoggingLevel, loggerName: String, marker: Marker?, msg: () -> Any?): String = - "${level.name}: [$loggerName] ${marker?.getName()} ${msg.toStringSafe()}" + public override fun formatMessage(includePrefix: Boolean, level: KotlinLoggingLevel, loggerName: String, marker: Marker?, msg: () -> Any?): String = + "${prefix(includePrefix, level, loggerName)}${marker?.getName()} ${msg.toStringSafe()}" public override fun formatMessage( + includePrefix: Boolean, level: KotlinLoggingLevel, loggerName: String, marker: Marker?, t: Throwable?, msg: () -> Any? ): String = - "${level.name}: [$loggerName] ${marker?.getName()} ${msg.toStringSafe()}${t.throwableToString()}" + "${prefix(includePrefix, level, loggerName)}${marker?.getName()} ${msg.toStringSafe()}${t.throwableToString()}" + + private fun prefix(includePrefix: Boolean, level: KotlinLoggingLevel, loggerName: String): String { + return if (includePrefix) { + "${level.name}: [$loggerName] " + } else { + "" + } + } private fun Throwable?.throwableToString(): String { if (this == null) { diff --git a/src/nativeMain/kotlin/mu/Formatter.kt b/src/nativeMain/kotlin/mu/Formatter.kt index 440caa3a..cf4b4907 100644 --- a/src/nativeMain/kotlin/mu/Formatter.kt +++ b/src/nativeMain/kotlin/mu/Formatter.kt @@ -1,10 +1,11 @@ package mu public interface Formatter { - public fun formatMessage(level: KotlinLoggingLevel, loggerName: String, msg: () -> Any?): String - public fun formatMessage(level: KotlinLoggingLevel, loggerName: String, t: Throwable?, msg: () -> Any?): String - public fun formatMessage(level: KotlinLoggingLevel, loggerName: String, marker: Marker?, msg: () -> Any?): String + public fun formatMessage(includePrefix: Boolean, level: KotlinLoggingLevel, loggerName: String, msg: () -> Any?): String + public fun formatMessage(includePrefix: Boolean, level: KotlinLoggingLevel, loggerName: String, t: Throwable?, msg: () -> Any?): String + public fun formatMessage(includePrefix: Boolean, level: KotlinLoggingLevel, loggerName: String, marker: Marker?, msg: () -> Any?): String public fun formatMessage( + includePrefix: Boolean, level: KotlinLoggingLevel, loggerName: String, marker: Marker?, diff --git a/src/nativeMain/kotlin/mu/KotlinLoggingConfiguration.kt b/src/nativeMain/kotlin/mu/KotlinLoggingConfiguration.kt index 1a453ca5..ca9091fe 100644 --- a/src/nativeMain/kotlin/mu/KotlinLoggingConfiguration.kt +++ b/src/nativeMain/kotlin/mu/KotlinLoggingConfiguration.kt @@ -2,6 +2,8 @@ package mu import kotlin.native.concurrent.AtomicReference +public expect val DefaultAppender: Appender + @Suppress("ObjectPropertyName") public object KotlinLoggingConfiguration { private val _logLevel = AtomicReference(KotlinLoggingLevel.INFO) @@ -10,7 +12,7 @@ public object KotlinLoggingConfiguration { set(value) { _logLevel.value = value } - private val _appender = AtomicReference(ConsoleOutputAppender) + private val _appender = AtomicReference(DefaultAppender) public var appender: Appender get() = _appender.value set(value) { diff --git a/src/nativeMain/kotlin/mu/internal/KLoggerLinux.kt b/src/nativeMain/kotlin/mu/internal/KLoggerLinux.kt index b43b1df3..d2f0fd6d 100644 --- a/src/nativeMain/kotlin/mu/internal/KLoggerLinux.kt +++ b/src/nativeMain/kotlin/mu/internal/KLoggerLinux.kt @@ -59,19 +59,19 @@ internal class KLoggerLinux( private fun KotlinLoggingLevel.logIfEnabled(msg: () -> Any?, logFunction: (String, String) -> Unit) { if (isLoggingEnabled()) { - logFunction(loggerName, formatter.formatMessage(this, loggerName, msg)) + logFunction(loggerName, formatter.formatMessage(appender.includePrefix, this, loggerName, msg)) } } private fun KotlinLoggingLevel.logIfEnabled(msg: () -> Any?, t: Throwable?, logFunction: (String, String) -> Unit) { if (isLoggingEnabled()) { - logFunction(loggerName, formatter.formatMessage(this, loggerName, t, msg)) + logFunction(loggerName, formatter.formatMessage(appender.includePrefix, this, loggerName, t, msg)) } } private fun KotlinLoggingLevel.logIfEnabled(marker: Marker?, msg: () -> Any?, logFunction: (String, String) -> Unit) { if (isLoggingEnabled()) { - logFunction(loggerName, formatter.formatMessage(this, loggerName, marker, msg)) + logFunction(loggerName, formatter.formatMessage(appender.includePrefix, this, loggerName, marker, msg)) } } @@ -82,7 +82,7 @@ internal class KLoggerLinux( logFunction: (String, String) -> Unit ) { if (isLoggingEnabled()) { - logFunction(loggerName, formatter.formatMessage(this, loggerName, marker, t, msg)) + logFunction(loggerName, formatter.formatMessage(appender.includePrefix, this, loggerName, marker, t, msg)) } }