Kermit icon indicating copy to clipboard operation
Kermit copied to clipboard

`OSLogStore` does not produce logs written to console by `platformLogWriter` on iOS

Open kirillzh opened this issue 2 years ago • 5 comments

https://developer.apple.com/documentation/oslog/oslogstore

kirillzh avatar Mar 14 '23 09:03 kirillzh

It looks like that's for reading, not writing: https://steipete.com/posts/logging-in-swift/. Unless I'm reading that wrong.

kpgalligan avatar Mar 14 '23 13:03 kpgalligan

Ah that's right, it's for reading only. The problem that I ran into is that platformLogWriter() didn't seem to write iOS console logs in a way where they would end up in the OSLogStore. Haven't tested with Kermit 2.0 yet though!

kirillzh avatar Mar 15 '23 00:03 kirillzh

This bug is still present as of Kermit v2.0.2. And it's a critical bug.

If the OSLogWriter is functioning properly, the log entries will be visible/available in the following locations:

  • Xcode's debug console
  • Console.app
  • OSLogStore API

The first 2 are working fine currently, but the last isn't.

The OSLogStore is an API for reading log entries that have been sent to OSLog system. For example, your application might want to export a log file, and send it to the development team for debugging. To do this, you MUST call the OSLogStore API within your code. If you do this now, with the current codebase, all log entries sent from Kermit result in a log message of <compose failure [UUID]>.

Unfortunately this renders Kermit unsuitable for use with many iOS applications, because it means:

  • any log entries sent thru Kermit are LOST
  • any kotlin-multiplatform libary that uses Kermit won't have readable log entries

To be clear: Kermit works fine if you're debugging on your own device when plugged into Xcode. But if you need to debug problems from actual users of your app, then you MUST use OSLogStore, and Kermit has unfortunately broken all log entries within OSLogStore.

robbiehanson avatar Oct 16 '23 20:10 robbiehanson

Totally agree with @robbiehanson . My current solution is to create a LogWriter in the app and pass it as a parameter to the kmm library.

final class MyLogger: LogWriter {
    private static let subsystem = Bundle.main.bundleIdentifier ?? "app_system"
    private let myLogger = Logger(subsystem: subsystem, category: "MyLogger")
    
    override func log(severity: Severity, message: String, tag: String, throwable: KotlinThrowable?) {
        #if APP_ENV_PROD
        myLogger("\(Date()) [MYLOGGER] [\(severity)] \(message, privacy: .private)")
        #else
        myLogger.debug("\(Date()) [MYLOGGER] [\(severity)] \(message, privacy: .public)")
        #endif
    }
}

marcodallaba avatar Nov 17 '23 07:11 marcodallaba