Skip to content

Commit

Permalink
Disable the OSLogWriter for now
Browse files Browse the repository at this point in the history
This log writer requires a patch in kermit.
See touchlab/Kermit#381 for details.

Also, the OSLog system is bugged anyway, so it should not be
used, until Apple releases a fix.
  • Loading branch information
dpad85 committed Feb 13, 2024
1 parent 8b68d1c commit ece812c
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 102 deletions.
217 changes: 116 additions & 101 deletions phoenix-shared/src/iosMain/kotlin/fr/acinq/phoenix/utils/OSLogWriter.kt
Original file line number Diff line number Diff line change
@@ -1,106 +1,121 @@
@file:OptIn(ExperimentalForeignApi::class, ExperimentalNativeApi::class)

package fr.acinq.phoenix.utils
// This file is commented as it requires a patch on kermit that fixes the OSLogWriter.
// As of kermit 2.0.2, log entries sent to the OSLogWriter result in a <compose failure> error.
// see https://github.com/touchlab/Kermit/issues/339
// proposed fix: https://github.com/touchlab/Kermit/pull/381
//
// Also:
//
// OSLog is currently broken anyway, due to a bug in the version released by Apple.
// Using is now (even with the patch above ^) would be pointless. In the meantime,
// we use swift-log with logs written to files (see FileLogger).

import co.touchlab.kermit.DefaultFormatter
import co.touchlab.kermit.LogWriter
import co.touchlab.kermit.Message
import co.touchlab.kermit.MessageStringFormatter
import co.touchlab.kermit.Severity
import co.touchlab.kermit.Tag
import co.touchlab.kermit.darwin.*
import kotlinx.cinterop.ExperimentalForeignApi
import kotlin.concurrent.AtomicReference
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_FAULT
import platform.darwin.OS_LOG_TYPE_INFO
import platform.darwin.os_log_type_t
import kotlin.experimental.ExperimentalNativeApi

/**
* This is based off the implementation in Kermit.
* Except their implementation is broken:
* https://github.com/touchlab/Kermit/pull/381
*/
@OptIn(ExperimentalNativeApi::class)
open class OSLogWriter internal constructor(
private val messageStringFormatter: MessageStringFormatter,
private val darwinLogger: DarwinLogger
) : LogWriter() {

constructor(
messageStringFormatter: MessageStringFormatter = DefaultFormatter
) : this(messageStringFormatter, DarwinLoggerActual)

override fun log(severity: Severity, message: String, tag: String, throwable: Throwable?) {
callLog(
severity, formatMessage(
severity = severity,
message = Message(message),
tag = Tag(tag)
), throwable
)
}

// Added to do some testing on log format. https://github.com/touchlab/Kermit/issues/243
open fun callLog(severity: Severity, message: String, throwable: Throwable?) {
val tag = "PhoenixShared.FooBar"
val type = kermitSeverityToOsLogType(severity)
darwinLogger.log(tag, type, message)
if (throwable != null) {
logThrowable(tag, type, throwable)
}
}

open fun logThrowable(tag: String, type: os_log_type_t, throwable: Throwable){
darwinLogger.log(tag, type, throwable.getStackTrace().joinToString("\n"))
}

private fun kermitSeverityToOsLogType(severity: Severity): os_log_type_t = when (severity) {
Severity.Verbose, Severity.Debug -> OS_LOG_TYPE_DEBUG
Severity.Info -> OS_LOG_TYPE_INFO
Severity.Warn -> OS_LOG_TYPE_DEFAULT
Severity.Error -> OS_LOG_TYPE_ERROR
Severity.Assert -> OS_LOG_TYPE_FAULT
}

open fun formatMessage(severity: Severity, tag: Tag, message: Message): String =
messageStringFormatter.formatMessage(null, tag, message)
}


internal interface DarwinLogger {
fun log(tag: String, type: os_log_type_t, message: String)
}

@OptIn(ExperimentalForeignApi::class)
private object DarwinLoggerActual : DarwinLogger {
private val _logMap = AtomicReference(mapOf<String, darwin_os_log_t>())
fun splitTag(tag: String): Pair<String, String> {
return when (val idx = tag.lastIndexOf(".")) {
-1 -> Pair("", tag)
else -> Pair(tag.substring(0, idx), tag.substring(idx+1))
}
}
fun getLog(tag: String): darwin_os_log_t {
var currentLogMap = _logMap.value
currentLogMap[tag]?.let { return it }
val (subsystem, category) = splitTag(tag)
val log = darwin_log_create(subsystem, category)!!
while (true) {
val newPair: Pair<String, darwin_os_log_t> = Pair(tag, log)
val updatedLogMap: Map<String, darwin_os_log_t> = currentLogMap.plus(newPair)
if (_logMap.compareAndSet(currentLogMap, updatedLogMap)) {
return log
} else {
currentLogMap = _logMap.value
currentLogMap[tag]?.let { return it }
}
}
}
override fun log(tag: String, type: os_log_type_t, message: String) {
darwin_log_with_type(getLog(tag), type, message)
}
}
//@file:OptIn(ExperimentalForeignApi::class, ExperimentalNativeApi::class)
//
//package fr.acinq.phoenix.utils
//
//import co.touchlab.kermit.DefaultFormatter
//import co.touchlab.kermit.LogWriter
//import co.touchlab.kermit.Message
//import co.touchlab.kermit.MessageStringFormatter
//import co.touchlab.kermit.Severity
//import co.touchlab.kermit.Tag
//import co.touchlab.kermit.darwin.*
//import kotlinx.cinterop.ExperimentalForeignApi
//import kotlin.concurrent.AtomicReference
//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_FAULT
//import platform.darwin.OS_LOG_TYPE_INFO
//import platform.darwin.os_log_type_t
//import kotlin.experimental.ExperimentalNativeApi
//
///**
// * This is based off the implementation in Kermit.
// * Except their implementation is broken:
// * https://github.com/touchlab/Kermit/pull/381
// */
//@OptIn(ExperimentalNativeApi::class)
//open class OSLogWriter internal constructor(
// private val messageStringFormatter: MessageStringFormatter,
// private val darwinLogger: DarwinLogger
//) : LogWriter() {
//
// constructor(
// messageStringFormatter: MessageStringFormatter = DefaultFormatter
// ) : this(messageStringFormatter, DarwinLoggerActual)
//
// override fun log(severity: Severity, message: String, tag: String, throwable: Throwable?) {
// callLog(
// severity, formatMessage(
// severity = severity,
// message = Message(message),
// tag = Tag(tag)
// ), throwable
// )
// }
//
// // Added to do some testing on log format. https://github.com/touchlab/Kermit/issues/243
// open fun callLog(severity: Severity, message: String, throwable: Throwable?) {
// val tag = "PhoenixShared.FooBar"
// val type = kermitSeverityToOsLogType(severity)
// darwinLogger.log(tag, type, message)
// if (throwable != null) {
// logThrowable(tag, type, throwable)
// }
// }
//
// open fun logThrowable(tag: String, type: os_log_type_t, throwable: Throwable){
// darwinLogger.log(tag, type, throwable.getStackTrace().joinToString("\n"))
// }
//
// private fun kermitSeverityToOsLogType(severity: Severity): os_log_type_t = when (severity) {
// Severity.Verbose, Severity.Debug -> OS_LOG_TYPE_DEBUG
// Severity.Info -> OS_LOG_TYPE_INFO
// Severity.Warn -> OS_LOG_TYPE_DEFAULT
// Severity.Error -> OS_LOG_TYPE_ERROR
// Severity.Assert -> OS_LOG_TYPE_FAULT
// }
//
// open fun formatMessage(severity: Severity, tag: Tag, message: Message): String =
// messageStringFormatter.formatMessage(null, tag, message)
//}
//
//
//internal interface DarwinLogger {
// fun log(tag: String, type: os_log_type_t, message: String)
//}
//
//@OptIn(ExperimentalForeignApi::class)
//private object DarwinLoggerActual : DarwinLogger {
// private val _logMap = AtomicReference(mapOf<String, darwin_os_log_t>())
// fun splitTag(tag: String): Pair<String, String> {
// return when (val idx = tag.lastIndexOf(".")) {
// -1 -> Pair("", tag)
// else -> Pair(tag.substring(0, idx), tag.substring(idx+1))
// }
// }
// fun getLog(tag: String): darwin_os_log_t {
// var currentLogMap = _logMap.value
// currentLogMap[tag]?.let { return it }
// val (subsystem, category) = splitTag(tag)
// val log = darwin_log_create(subsystem, category)!!
// while (true) {
// val newPair: Pair<String, darwin_os_log_t> = Pair(tag, log)
// val updatedLogMap: Map<String, darwin_os_log_t> = currentLogMap.plus(newPair)
// if (_logMap.compareAndSet(currentLogMap, updatedLogMap)) {
// return log
// } else {
// currentLogMap = _logMap.value
// currentLogMap[tag]?.let { return it }
// }
// }
// }
// override fun log(tag: String, type: os_log_type_t, message: String) {
// darwin_log_with_type(getLog(tag), type, message)
// }
//}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ actual fun phoenixLogWriters(ctx: PlatformContext): List<LogWriter> {
return if (ctx.logger != null) {
listOf(PassthruLogWriter(ctx))
} else {
listOf(OSLogWriter())
// OSLogWriter is disabled for now, as the current version of OSLogStore is buggy
// listOf(OSLogWriter())
throw IllegalArgumentException("A valid logger must be provided. OSLogWriter is disabled.")
}
}

0 comments on commit ece812c

Please sign in to comment.