{"__v":13,"_id":"5676c05fa7d01d0d0034fa79","category":{"__v":6,"_id":"56730183547bee0d00997d1a","pages":["5673025a30d9800d003a2ea8","56730268cae8410d008a10b6","5673027030d9800d003a2eaa","567344caf65d9c0d002e3c89","56735274f65d9c0d002e3c9b","5676c05fa7d01d0d0034fa79"],"project":"5672fc989996590d00c22c65","version":"5672fc989996590d00c22c68","sync":{"url":"","isSync":false},"reference":false,"createdAt":"2015-12-17T18:40:03.307Z","from_sync":false,"order":1,"slug":"beginners","title":"Operation Features"},"project":"5672fc989996590d00c22c65","user":"5654ea8be0d82b0d00ab5747","version":{"__v":7,"_id":"5672fc989996590d00c22c68","project":"5672fc989996590d00c22c65","createdAt":"2015-12-17T18:19:04.699Z","releaseDate":"2015-12-17T18:19:04.699Z","categories":["5672fc999996590d00c22c69","567301169d4c060d009da8b3","56730183547bee0d00997d1a","5673018a06b19d0d0010691b","567301b53054630d00fe9288","567400638565060d009a86fb","5674017bf79ca90d00ad2f67"],"is_deprecated":false,"is_hidden":false,"is_beta":false,"is_stable":true,"codename":"","version_clean":"2.5.0","version":"2.5.0"},"updates":[],"next":{"pages":[],"description":""},"createdAt":"2015-12-20T14:51:11.902Z","link_external":false,"link_url":"","githubsync":"","sync_unique":"","hidden":false,"api":{"results":{"codes":[]},"settings":"","auth":"required","params":[],"url":""},"isReference":false,"order":2,"body":"`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.\n\nFor example\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"class LogExample: Operation {\\n   \\n    override func execute() {\\n        log.info(\\\"Hello World!\\\")\\n        finish()\\n    }\\n}\",\n      \"language\": \"swift\",\n      \"name\": \"log example\"\n    }\n  ]\n}\n[/block]\nThere are five levels of severity: `.Verbose`, `.Notice`, `.Info`, `.Warning` and `.Fatal`.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"// Internally the framework uses .Verbose to describe state transitions so, it can be very chatty.\\nlog.verbose(\\\"Really chatty, handy for caveman debugging!\\\")\\n\\nlog.notice(\\\"Public service announcements etc\\\")\\nlog.info(\\\"Print out info\\\")\\n\\n// Internally the framework will log warnings when an operation finishes with an error.\\nlog.warning(\\\"Received a recoverable error.\\\")\\nlog.fatal(\\\"Something is seriously broken\\\")\",\n      \"language\": \"swift\",\n      \"name\": \"internal operation logs\"\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Default severity threshold\"\n}\n[/block]\nThe 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\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {\\n\\n    LogManager.severity = .Notice\\n    return true\\n}\",\n      \"language\": \"swift\",\n      \"name\": \"setting default log severity\"\n    }\n  ]\n}\n[/block]\nDuring 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.\n\nIf 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. \n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Default enabled\"\n}\n[/block]\nLogging can be disabled entirely too:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"LogManager.enabled = false\",\n      \"language\": \"swift\",\n      \"name\": \"disabled logging\"\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Individual overrides\"\n}\n[/block]\nEach `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.\n\nHowever, 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.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"class LogExample: Operation {\\n   \\n   override init() {\\n       super.init()\\n       name = \\\"Log Example\\\"\\n       log.severity = .Verbose\\n   }\\n   \\n    override func execute() {\\n        log.verbose(\\\"Hello World!\\\")\\n        finish()\\n    }\\n}\",\n      \"language\": \"swift\",\n      \"name\": \"override log severity\"\n    }\n  ]\n}\n[/block]","excerpt":"Internal log property available to `Operation` subclasses","slug":"logging","type":"basic","title":"Logging"}

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 [block:code] { "codes": [ { "code": "class LogExample: Operation {\n \n override func execute() {\n log.info(\"Hello World!\")\n finish()\n }\n}", "language": "swift", "name": "log example" } ] } [/block] There are five levels of severity: `.Verbose`, `.Notice`, `.Info`, `.Warning` and `.Fatal`. [block:code] { "codes": [ { "code": "// Internally the framework uses .Verbose to describe state transitions so, it can be very chatty.\nlog.verbose(\"Really chatty, handy for caveman debugging!\")\n\nlog.notice(\"Public service announcements etc\")\nlog.info(\"Print out info\")\n\n// Internally the framework will log warnings when an operation finishes with an error.\nlog.warning(\"Received a recoverable error.\")\nlog.fatal(\"Something is seriously broken\")", "language": "swift", "name": "internal operation logs" } ] } [/block] [block:api-header] { "type": "basic", "title": "Default severity threshold" } [/block] 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 [block:code] { "codes": [ { "code": "func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {\n\n LogManager.severity = .Notice\n return true\n}", "language": "swift", "name": "setting default log severity" } ] } [/block] 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. [block:api-header] { "type": "basic", "title": "Default enabled" } [/block] Logging can be disabled entirely too: [block:code] { "codes": [ { "code": "LogManager.enabled = false", "language": "swift", "name": "disabled logging" } ] } [/block] [block:api-header] { "type": "basic", "title": "Individual overrides" } [/block] 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. [block:code] { "codes": [ { "code": "class LogExample: Operation {\n \n override init() {\n super.init()\n name = \"Log Example\"\n log.severity = .Verbose\n }\n \n override func execute() {\n log.verbose(\"Hello World!\")\n finish()\n }\n}", "language": "swift", "name": "override log severity" } ] } [/block]