diff --git a/kermit-core/src/appleMain/kotlin/co/touchlab/kermit/OSLogWriter.kt b/kermit-core/src/appleMain/kotlin/co/touchlab/kermit/OSLogWriter.kt index 6512c386..4216c088 100644 --- a/kermit-core/src/appleMain/kotlin/co/touchlab/kermit/OSLogWriter.kt +++ b/kermit-core/src/appleMain/kotlin/co/touchlab/kermit/OSLogWriter.kt @@ -12,8 +12,6 @@ package co.touchlab.kermit import co.touchlab.kermit.darwin.* import kotlinx.cinterop.ExperimentalForeignApi -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 @@ -30,9 +28,9 @@ open class OSLogWriter internal constructor( private val darwinLogger: DarwinLogger, ) : LogWriter() { - constructor(messageStringFormatter: MessageStringFormatter = DefaultFormatter, subsystem: String = "", category: String = "") : this( + constructor(messageStringFormatter: MessageStringFormatter = DefaultFormatter, subsystem: String = "", category: String = "", publicLogging: Boolean = false) : this( messageStringFormatter, - DarwinLoggerActual(subsystem, category), + DarwinLoggerActual(subsystem, category, publicLogging), ) override fun log(severity: Severity, message: String, tag: String, throwable: Throwable?) { @@ -77,9 +75,18 @@ internal interface DarwinLogger { } @OptIn(ExperimentalForeignApi::class) -private class DarwinLoggerActual(subsystem: String, category: String) : DarwinLogger { +private class DarwinLoggerActual(subsystem: String, category: String, publicLogging: Boolean) : DarwinLogger { private val logger = darwin_log_create(subsystem, category)!! + // see https://developer.apple.com/documentation/os/logging/generating_log_messages_from_your_code?language=objc + // iOS considers everything coming from Kermit as a dynamic string, so without publicLogging=true, all logs are + // private + private val darwinLogFn: (osLogSeverity: os_log_type_t, message: String) -> Unit = if (publicLogging) { + { osLogSeverity, message -> darwin_log_public_with_type(logger, osLogSeverity, message) } + } else { + { osLogSeverity, message -> darwin_log_with_type(logger, osLogSeverity, message) } + } + override fun log(osLogSeverity: os_log_type_t, message: String) { - darwin_log_with_type(logger, osLogSeverity, message) + darwinLogFn(osLogSeverity, message) } } diff --git a/kermit-core/src/nativeInterop/cInterop/os_log.def b/kermit-core/src/nativeInterop/cInterop/os_log.def index baed7c77..62f4dd67 100644 --- a/kermit-core/src/nativeInterop/cInterop/os_log.def +++ b/kermit-core/src/nativeInterop/cInterop/os_log.def @@ -19,3 +19,12 @@ darwin_os_log_t darwin_log_create(const char *subsystem, const char *category) { void darwin_log_with_type(darwin_os_log_t log, os_log_type_t type, const char *msg) { os_log_with_type((os_log_t)log, type, "%s", msg); } + +/** + * Uses format specifier %{public}s to make logging public. + * See https://developer.apple.com/documentation/os/logging/generating_log_messages_from_your_code?language=objc. + * We cannot pass the format specifier from Kotlin, as the API requires the value to be a string constant. + */ +void darwin_log_public_with_type(darwin_os_log_t log, os_log_type_t type, const char *msg) { + os_log_with_type((os_log_t)log, type, "%{public}s", msg); +}