touchlab / Kermit

Kermit by Touchlab is a Kotlin Multiplatform centralized logging utility.
https://kermit.touchlab.co
Apache License 2.0
699 stars 40 forks source link

Stack trace on iOS is not shown by default in the OS logs #395

Closed rocketraman closed 4 months ago

rocketraman commented 4 months ago

I'm running a Kotlin multiplatform as a library within a React Native application.

With Kermit's default settings, which uses XcodeSeverityWriter, the stack trace is not shown anywhere. I'm looking in Console.app. However, according to https://stackoverflow.com/questions/10165641/how-can-i-get-the-console-logs-from-the-ios-simulator, standard output will only be shown in the XCode debug window.

This seems to be a poor default. Should the default be to use the OSLogWriter so that at least some stack trace is shown in all cases, and then allow users to specify XcodeSeverityWriter if they wish to see full traces in the XCode debug console?

kpgalligan commented 4 months ago

Should the default be to use the OSLogWriter so that at least some stack trace is shown in all cases, and then allow users to specify XcodeSeverityWriter if they wish to see full traces in the XCode debug console?

I would expect many more Xcode users to complain that the stack trace was truncated (which is why the default works as it does now). Using a KMP library in a react native application would certainly seem to be the less likely scenario vs an iOS dev using a KMP library from Swift and Xcode. Would it not make sense to let you specify a different writer for an uncommon use case rather than making a less common use case the default?

kpgalligan commented 4 months ago

To follow up, that is what OSLogWriter is for. XcodeSeverityWriter is the "default" for iOS because 99% (guessing, but not far off) of people starting with KMP are running from Xcode. The default factory function platformLogWriter, as described in the comment describing it:

Factory function to return a default LogWriter for each platform. The LogWriter is targeted at local development.

The variety of platform loggers makes a "sensible default" an exercise in compromise. Specifically the XcodeSeverityWriter adds color emojis, etc, to make it "more usable" from Xcode specifically. The decision to print the stack trace to stdout was a practical one based on how unusable stack traces could be when truncated.

rocketraman commented 4 months ago

That's fair. The logging situation on iOS seems to be a bit of a mess.

kpgalligan commented 4 months ago

They're all a mess in their own way. The xcode situation is weird, though.

I wonder if there's value in having different default functions. Not sure how it would work, but if you knew the consumer of the code would be calling from react native, you could call the "reactNativePlatformLogWriter()" factory function instead to init loggers inside the KMP code.

rocketraman commented 4 months ago

They're all a mess in their own way. The xcode situation is weird, though.

Yeah, coming from a backend developer's perspective (Log4j, etc.) I religiously avoid standard output for long-running apps, it felt odd to me that we would intentionally write log information to standard output, despite the underlying reasoning. It sucks that that is necessary. Perhaps an alternate solution is chunking output? I don't know if the truncation happens at line length or overall size.

Look at this (closed but never solved AFAIK) issue for more background reading about React Native + logging on iOS: https://github.com/facebook/react-native/issues/9441.

you could call the "reactNativePlatformLogWriter()" factory function instead to init loggers inside the KMP code

Even when not using React Native, I often install and run iOS apps from the command line rather than from XCode e.g.

xcodebuild ...

xcrun simctl install booted ~/Library/Developer/Xcode/DerivedData/iosApp-xxx/Build/Products/Debug-iphonesimulator/ios.app

xcrun simctl launch booted my.app.id

Though I note that launch has a --console-pty (as opposed to --console) in there that captures standard output in addition to the logging output, so the XcodeSeverityWriter printing stack traces to standard output should work if that flag is used, I believe.

But the name reactNativePlatformLogWriter seems too tightly tied to React Native when what we are really saying is we want all log output to go to logs, and not be mixed logs+stdout -- there may be situations other than react native in which that is true.