I am doing a bunch of logging when I'm testing my application which is useful for getting information about variable state and such.
However I have read that you should use logging sparsely in production code (because it can potentially slow down your application). But my question is now: if my app is in production and people are using it, whenever a crash (god forbid) occurs, how will I be able to interpret the crash information if I have removed the logging statements? Then I suppose I will only have a stacktrace for me to interpret?
Does this mean I should leave logging in production code only WHERE it's really essential for me to interpret what has happened?
Also how will the logging statements relate to the crash reports? Will they be combined? I'm thinking of using Flurry as analytics and crash reports...
You most definitely should include lots of logging in your released app. As you suspect, it can help you immensely when debugging, and it can even help your power users self-debug if you make sure your log messages are well-worded, reasonably self-explanatory and include all the relevant details.
There are many aspects to a good logging system. There's a few common patterns that are often good to follow (though on iOS specifically some apply more-so than others):
- Distinguish your logs by severity. Errors, warnings, informative, debug, for example. Syslog does this, as another example. In addition to helping you focus on more severe problems first, you can set a minimum level for your release build of "informative", say, and thus exclude the more verbose debug ones, while keeping most all the ones you'll need when things go wrong. That way you trim out log messages that may be very verbose or frequent (and thus risk slowing down your app) but leave in important ones.
- Allow configuration of logging levels at runtime (typically done via command-line flags, though not on iOS obviously). For example, you could by default show only warnings and errors, but optionally expand that via a flag.
- Include file name and line number in all log messages, at least in debug builds. You may have reservations about including file names in release builds, but at least include the line number - it'll help ensure you're looking at the right code come debugging time; you may (accidentally or intentionally) have similar-looking log statements from multiple places in the same file.
- Write your log messages in plain English, with good grammar and minimal abbreviations, and include the values of all relevant variables. Also include a statement about the consequences of the condition, in the case of errors or warnings. e.g. "Unable to connect to someserver:1234 - error -18 (ETIMEOUT). Cannot determine if there are app updates available.".
- Minimise user-sensitive data in your logs, and be very careful what you do with any logs that contain it. Don't ever log passwords or things of that nature - not even ancillary things like their length, or hashes. Be mindful that even something seemingly benign like a website address they provide can be considered sensitive (they might not want it known that they frequent www.lumberjacksandpressedwildflowers.com). This is especially important if you have any kind of transmission of those logs - you'll need to adopt SSL etc.
You can get a lot of these features from pre-built logging systems, e.g. CocoaLumberjack and NSLogger (or both). No doubt there's others.