Logging

Internal log property available to Operation subclasses

Operation has a log property which can be used to observe scheduling and execution. It support some standard logging features such as a dedicated serial queue, and levels of severity with a threshold.

For example

class LogExample: Operation {
   
    override func execute() {
        log.info("Hello World!")
        finish()
    }
}

There are five levels of severity: .Verbose, .Notice, .Info, .Warning and .Fatal.

// Internally the framework uses .Verbose to describe state transitions so, it can be very chatty.
log.verbose("Really chatty, handy for caveman debugging!")

log.notice("Public service announcements etc")
log.info("Print out info")

// Internally the framework will log warnings when an operation finishes with an error.
log.warning("Received a recoverable error.")
log.fatal("Something is seriously broken")

Default severity threshold

The default severity threshold is set on the LogManager and is .Warning. This means that by default, only .Warning and .Fatal logs are displayed. This can be adjusted, say in your AppDelegate's didFinishLaunchingWithOptions method

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

    LogManager.severity = .Notice
    return true
}

During development of your app, .Notice can be a good setting, as it will provide quite a rich debug setting, yet avoid too much noise from the the framework itself.

If you are encountering scheduling issues, switching to .Verbose will give lots more output about an Operation's state, such as when it is pending, evaluating conditions, starting or finishing.

Default enabled

Logging can be disabled entirely too:

LogManager.enabled = false

Individual overrides

Each Operation subclass creates a Logger using defaults from the LogManager. This means that changes to the LogManager after an Operation has been initialized will not be respected.

However, this does mean that each logger can override the global behavior. This can be especially useful to debug an individual operation at a lower threshold than all the other operations.

class LogExample: Operation {
   
   override init() {
       super.init()
       name = "Log Example"
       log.severity = .Verbose
   }
   
    override func execute() {
        log.verbose("Hello World!")
        finish()
    }
}