-
Notifications
You must be signed in to change notification settings - Fork 102
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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
Showing
2 changed files
with
119 additions
and
102 deletions.
There are no files selected for viewing
217 changes: 116 additions & 101 deletions
217
phoenix-shared/src/iosMain/kotlin/fr/acinq/phoenix/utils/OSLogWriter.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | ||
// } | ||
//} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters