Friday, December 10, 2021

OSLogStore on Monterey

Quinn the Eskimo:

So, let’s start with some history:

  • macOS programs have been able to read log messages since the introduction of OSLogStore on macOS 10.15.

  • This API is not available on iOS-based platforms.

  • In iOS 14 beta we added the OSLog framework to the iOS SDK, along with a new initialiser to OSLogStore that allowed iOS apps to read their own log messages.

  • Unfortunately this feature didn’t work properly )-: and so it was removed very late in the iOS 14 beta cycle.

  • It’s now several months later and the feature has not returned (up to and including iOS 14.5b5).

I have no concrete info to share about when this feature will return; in fact, I can’t even confirm that it will return. What I can say is that the OSLog team are well aware of the demand for this feature from third-party developers.


Gaining access to the local unified logging system requires permission from the system. The caller must be run by an admin account and have the entitlement.

Quinn the Eskimo:

This is good news / bad news story:

  • The bad news is that there’s no way for a third-party developer to get the entitlement.

  • The good news is that it’s not necessary: As long as you’re running as an admin user, you don’t need the entitlement.

  • The bad news is that this won’t work from within the App Sandox. AFAICT there’s no way for a third-party sandboxed app to access the log store.

Peter Steinberger:

As of iOS 15 and macOS Monterey, OSLogStore works just as expected. No entitlements or hacks needed. It works in the Simulator, on device, on macOS and macOS Catalyst. Try out the OSLogTest project here.

The local() log store and .system scope still don’t work in the sandbox. You’ll just get an error like:

Error Domain=OSLogErrorDomain Code=10 "Connection to logd failed" UserInfo={NSLocalizedDescription=Connection to logd failed, _OSLogErrorInternalCode=15}

From a sandboxed app, you can only use the .currentProcessIdentifier scope. Not having access to the entire system log does make some sense for privacy reasons, but it really reduces the usefulness of OSLogStore:

So, OSLogStore offers a nicer API than /usr/bin/log, but it is still very limited. In practice, I find that I still need to implement my own log persistence, which is too bad because in theory os_log has already solved hard problems like:

And, since os_log doesn’t have a pluggable backend, it needs to be isolated behind another layer in your app if you ever want to be able to access your own logs. Apple even has an open-source project for doing this.

SwiftLog (via Mattt Thompson):

This package only provides the logging API itself and therefore SwiftLog is a ‘logging API package’. SwiftLog (using LoggingSystem.bootstrap) can be configured to choose any compatible logging backend implementation. This way packages can adopt the API and the application can choose any compatible logging backend implementation without requiring any changes from any of the libraries.


Update (2021-12-16): Saagar Jha:

It’s kind of weird that NSLog really hasn’t gotten a replacement at all for print debugging on Apple’s platforms. It just packs in so many of the right choices for this use case that everyone (myself included) finds themselves reaching for it all the time. Even from Swift!


Nobody is going to pull in a third party library or write a wrapper around something just for a debugging session, so the alternatives are what, print(f) and os_log? I use the former a bunch and the latter occasionally, but they often just aren’t what I need…

os_log is…cool, but cumbersome. You have to import a thing, then set up a logger, then you give it a static string, plus a category or whatever. And after all that work, it doesn’t even show up in Xcode! And in Console it’s redacted or at a low level so you don’t see it…

See also: Making os_log Public on macOS Catalina.

Comments RSS · Twitter

Leave a Comment