Does OSLog.isEnabled(type: .debug) actually work?

My iOS app has a function that logs a whole load of statistics about a particular object. Since this is only for dev purposes I don't want any of the actual statistics gathering to be run if debug logs are not enabled so I am checking OSLog.default.isEnabled(type: .debug) before doing anything. Here is the basic shell of my code:

Code Block swift
    func dumpStatistics(for item: Any) {
        func callSomeVerySlowFunc(_ object: Any) -> String {
           /* Something much more complicated than this */
            return "Hello"
        }
        guard OSLog.default.isEnabled(type: .debug) else {
            NSLog("Not dumping Statistics, debug logging is disabled")
            return
        }
        NSLog("(NSLog) dumping Statistics, debug logging is supposedly enabled")
        os_log(.debug, "(os_log)dumping Statistics, debug logging is supposedly enabled")
        let stats: String = callSomeVerySlowFunc(item)
        NSLog("(NSLog) dumping Statistics: %@", stats)
        os_log(.debug, "(os_log) dumping Statistics: %{public}@", stats)
    }

When "Show Debug Info" is enabled in Console, this is what I get (as expected):

(NSLog) dumping Statistics, debug logging is supposedly enabled

(os_log)dumping Statistics, debug logging is supposedly enabled

(NSLog) dumping Statistics: Hello

(os_log) dumping Statistics: Hello

When "Show Debug Info" is disabled, this is what I expect to get:

 Not dumping Statistics, debug logging is disabled

However, this is what I actually do get:

(NSLog) dumping Statistics, debug logging is supposedly enabled

(NSLog) dumping Statistics: Hello

This implies that OSLog.default.isEnabled(type: .debug) is always returning true, but the actual logging code itself knows it's not really enabled.

So this has the effect that I go through all the expense of calculating the statistics when I shouldn't.

(BTW - I added the NSLog calls to help me see what was really happening. I don't intend to keep them in there)

I don't think I am doing anything wrong in my code.

I'm running macOS 10.15.7 alongside two iPads, one with iOS 14.3 and one with 14.4. Both iPads are connected via USB
Post not yet marked as solved Up vote post of Wellington Down vote post of Wellington
1.3k views

Replies

I’m not 100% sure what’s going on in your case, but this is working how I expected it to work. Here’s what I did:
  1. I created a new iOS app with a single status label.

  2. I added the code below to my main view controller.

  3. I ran it from Xcode. The label said enabled.

  4. I stopped it in Xcode.

  5. I disconnected the USB cable.

  6. I ran it from the Home screen. The label said disabled.

This is using Xcode on macOS 12.2 targeting iOS 14.4.

And here’s my code:

Code Block
override func viewDidLoad() {
super.viewDidLoad()
self.statusLabel.text = OSLog.default.isEnabled(type: .debug) ? "enabled" : "disabled"
}


Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
What happens if you run it from the Home screen with the USB cable connected and the Console app actually displaying that phone's logs (with and without "Include Debug Messages")? I wonder if I'm hitting an observer effect here.
The gating factor seems to be running Console with the device selected and streaming enabled.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"