Enable debug logging through OSLog

1.3k Views Asked by At

I've set up logging through OSLog in my iOS App, and I've added a button to export logs with OSLogStore:

extension OSLog {
    private static let subsystem = Bundle.main.bundleIdentifier!
   
    @available(iOS 15.0, *)
    static func getLogs(inLast: TimeInterval) -> [OSLogEntryLog]? {
        guard let store = try? OSLogStore(scope: .currentProcessIdentifier) else { return nil }
        let startTime = store.position(timeIntervalSinceEnd: -inLast)
        guard let entries = try? store.getEntries(at: startTime).compactMap({ $0 as? OSLogEntryLog }).filter({ $0.subsystem == subsystem }) else { return nil }
        return entries
    }
}

This works fine when testing locally, all logs are exported even in release builds. However, when our team is testing builds through TestFlight, debug logs are not exported. Is there a way to export all logs including debug logs?

2

There are 2 best solutions below

0
Annett Schwarze On

Claus Jørgensen's answer works. One can indeed add the settings to an Info.plist and the debug level messages appear in OSLogStore on iOS. From reading Apple's documentation, I was assuming that the configuration of these things is only possible in macOS.

In case it helps anybody: Some information about the Info.plist is in man 5 os_log:

Application-specific profiles are in an application's Info.plist file, in an OSLogPreferences dictionary. Keys in this dictionary correspond to subsystem names, and its values are subsystem dictionaries.

I suspect, that debug level messages are not accessible from the OSLogStore - at least currently with iOS 17 / Xcode 15. From Apple's documentation ([Generating Log Messages from Your Code][1]):

Normally, the system stores debug and info messages only in memory, ...

and:

The severity of the log level impacts the speed at which the system logs the information. Debug logs have very low overhead because the system stores them only in memory.

From what one can see when playing with OSLogStore on iOS, it looks like OSLogStore just does not include debug messages.

2
Claus Jørgensen On

You need to add this to your Info.plist

<key>OSLogPreferences</key>
<dict>
    <key>your.subsystem.key.here</key>
    <dict>
        <key>your-category-here</key>
        <dict>
            <key>Level</key>
            <dict>
                <key>Enable</key>
                <string>Debug</string>
                <key>Persist</key>
                <string>Debug</string>
            </dict>
        </dict>
    </dict>
</dict>

Also, you might want to add

<key>Enable-Private-Data</key>
<true/>

to the same dictionary to not have all your parameters redacted.

And finally, don't use .filter on the getEntries() result, it's extremely slow. Instead use the matching overload with a NSPredicate, e.g.

try? store
    .getEntries(
        at: startTime, 
        matching: NSPredicate(format: "subsystem == \"\(subsystem)\"")
    )
    .compactMap({ $0 as? OSLogEntryLog })