Is there any way of adjusting logging level dynamically at run time?

I've gone through several tutorials, and the documentation, it seems there's no way to adjust the logging level dynamically, or even at build time for that matter.

i.e. there is apparently nothing that exists such as:

static let logger = Logger(subsystem: subsystem(), category: category())
logger.setMinimalLevel(.Warning)
logger.trace("I won't get displayed because minimal level is debug")

Am I mistaken and there is something like this?

Replies

It's a bit unclear what you mean by "adjust the logging level dynamically". Are you saying that, for any given log function call in your code, you want it to default to a log level that can be dynamically adjusted by other code? Or, are you saying that you want to choose dynamically what message levels are suppressed, even though each call site specifies (or defaults) its level statically?

I would start with the information here:

https://developer.apple.com/documentation/os/logging/customizing_logging_behavior_while_debugging

and note that you could extend the Logger type with custom behaviors (that call through to its standard behaviors). It's also a value type, so there's no real downside to having multiple instances (possibly configured differently, if that turns out to help).

@Polyphonic what I mean is having the ability to turn on or off certain levels of logging without have to change the code or a setting and recompile and run again.

i.e. suppose the app is released on the App Store and consequently it has verbose logging turned off. But if a user reports a bug customer support could instruct them to long press in a support screen for example and that has the effect of turning on verbose logging for say 24 hours and customer support could instruct the user to recreate the issue. There are various libraries that can capture the console output and can send it off for analysis.

The iOS native equivalent of Cocoalumberjack's DDLogLevel.setLevel(level).

I know I could implement a mechanism like this by building in if statements etc., but it would be cleaner and easier if there's some native functionality that will just do it with a single line change. CocoaLumberjack logging can be directed to the console and be affected by the set level, but it's a bit funky and I'd like to explore using iOS native logging instead. (CocoaLumberjack logging can also be directed to a file, so verbose logging could be piped there and that file sent when the user contacts customer support, but I'm looking at all angles.)

P.S. I'm seeing this line appearing often in the console "Shutting down live logging", would you happen to know what that means and its cause?

Cheers

@Polyphonic

Here's a code example illustrating what I mean. In the code below, which of the Cocoalumberjack lines that get logged can be controlled by what level is set in DDLog.add(consoleLogger, with: .warning), if this code is run only two lines of CocoaLumberjack output will be displayed, this can be increased or decreased by changing what is pass to DDLog.add(). My question, is is there an equivalent for the iOS native logging?

    let consoleLogger = DDOSLogger.sharedInstance
    DDLog.add(consoleLogger, with: .warning)

    NSLog("NSLog Cocoalumberjack:")
    DDLogVerbose( DDLogVerbose")
    DDLogInfo("DDLogInfo")
    DDLogDebug("DDLogDebug")
    DDLogWarn("DDLogWarn")
    DDLogError("DDLogError")
    
    if #available(iOS 14.0, *) {
        NSLog("NSLog Native:")
        let defaultLog = Logger()
        defaultLog.trace("Logger TRACE")
        defaultLog.info("Logger INFO")
        defaultLog.debug("Logger DEBUG")
        defaultLog.notice("Logger NOTICE")
        defaultLog.warning("Logger WARNING")
        defaultLog.error("Logger ERROR")
    }