Skip to content

Commit

Permalink
iOS public logging (#408)
Browse files Browse the repository at this point in the history
* iOS public logging

Resolves #400

* OSLogWriter public logging by configuration

---------

Co-authored-by: Kevin Schildhorn <kevin.schildhorn@gmail.com>
  • Loading branch information
rocketraman and KevinSchildhorn authored Nov 15, 2024
1 parent 30b0c78 commit 5f5fc07
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 6 deletions.
19 changes: 13 additions & 6 deletions kermit-core/src/appleMain/kotlin/co/touchlab/kermit/OSLogWriter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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?) {
Expand Down Expand Up @@ -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)
}
}
9 changes: 9 additions & 0 deletions kermit-core/src/nativeInterop/cInterop/os_log.def
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

0 comments on commit 5f5fc07

Please sign in to comment.