Best Practices for Error Logging and/or reporting for iPhone
Asked Answered
L

4

30

When I do web development, I use a custom made logger that catches fatal errors and appends a trace to a file and displays a message to the user. I can occasionally glance to see if the file changed, which means, some user encountered an error and I can dig in to see what they encountered.

I'd like something similar on the iphone, with some caveats:

  • While developing, it should be trivial to reset the list of errors or turn off notification.
  • While developing, the error messages should also show up in some obvious place, like on the screen on in the console
  • Once deployed, errors should politely be sent to the mothership for analysis (for a bug fix in the next update)
  • Turn on Trace/Info logging when trying to track down a problem during development
  • Turn off console logging for 'Release' to speed up things for the user
  • Should clean-up after itself so as to be a good citizen on the phone

Some Related Links

It seem like there would be a common toolkit to do this - how do you handle this?

[Update Oct 2011] There have been some developments, of varying maturity...

  • PLCrashReporter.
  • Quincy sits on top of PLC.
  • Bugsense commercial crash reporter.
  • Crittercism crash and error reporting (some free packages, some paid).
  • Test flight now has an SDK that catches crashes (but not yet for app store apps, just dev apps).
  • Like Test Flight, Hockey aims to combine ad hoc distribution with crash reporting.
Lissa answered 3/11, 2009 at 15:22 Comment(3)
I was trying to figure out why I only got a 50 rep bonus for my accepted answer. It seems that Stackoverflow automatically accepted my answer and gave me half the bounty: meta.stackexchange.com/questions/26510/…Ailbert
Bummer - as the author, I would have accepted your answer, but by the time I came back to check on things, Stackoverflow had already accepted the answer on my behalf, which I thought was sort of rude. It had only been a few days. Ok - I just up-voted your answer for good measure! Thanks.Lissa
GSLog depends on GraphicsServices which appears to be private framework.Ting
A
38

Here's what we do:

  • Let the iPhone handle its own crash dumps through the existing App Store mechanisms. Update: having found iTunes Connect to be unreliable at providing crash reports, I recommend using Fabric/Crashlytics, or a competitor like Crittercism or Rollbar.
  • Our released product has no trace in, this seems to be consistent with what most other iPhone apps do.
  • If a bug is reported then we reproduce it using a traced build.

In more detail:

  • We define macros to NSLog trace at numerous different levels of granularity.
  • Use Xcode build settings to change the trace level, which controls how much trace gets compiled into the product, e.g. there are Release and Debug build configurations.
  • If no trace level is defined then we show full trace in the Simulator, and no trace when running on a real Device.

I've included example code below showing how we've written this, and what the output looks like.

We define multiple different trace levels so developers can identify which lines of trace are important, and can filter out lower level detail if they want to.

Example code:

- (void)myMethod:(NSObject *)xiObj
{
  TRC_ENTRY;
  TRC_DBG(@"Boring low level stuff");
  TRC_NRM(@"Higher level trace for more important info");
  TRC_ALT(@"Really important trace, something bad is happening");
  TRC_ERR(@"Error, this indicates a coding bug or unexpected condition");
  TRC_EXIT;
}

Example trace output:

2009-09-11 14:22:48.051 MyApp[3122:207] ENTRY:+[MyClass myMethod:]
2009-09-11 14:22:48.063 MyApp[3122:207] DEBUG:+[MyClass myMethod:]:Boring low level stuff
2009-09-11 14:22:48.063 MyApp[3122:207] NORMAL:+[MyClass myMethod:]:Higher level trace for more important info
2009-09-11 14:22:48.063 MyApp[3122:207] ALERT:+[MyClass myMethod:]:Really important trace, something bad is happening
2009-09-11 14:22:48.063 MyApp[3122:207] ERROR:+[MyClass myMethod:]:Error, this indicates a coding bug or unexpected condition
2009-09-11 14:22:48.073 MyApp[3122:207] EXIT:+[MyClass myMethod:]

Our trace definitions:

#ifndef TRC_LEVEL
#if TARGET_IPHONE_SIMULATOR != 0
#define TRC_LEVEL 0
#else
#define TRC_LEVEL 5
#endif
#endif

/*****************************************************************************/
/* Entry/exit trace macros                                                   */
/*****************************************************************************/
#if TRC_LEVEL == 0
#define TRC_ENTRY    NSLog(@"ENTRY: %s:%d:", __PRETTY_FUNCTION__,__LINE__);
#define TRC_EXIT     NSLog(@"EXIT:  %s:%d:", __PRETTY_FUNCTION__,__LINE__);
#else
#define TRC_ENTRY
#define TRC_EXIT
#endif

/*****************************************************************************/
/* Debug trace macros                                                        */
/*****************************************************************************/
#if (TRC_LEVEL <= 1)
#define TRC_DBG(A, ...) NSLog(@"DEBUG: %s:%d:%@", __PRETTY_FUNCTION__,__LINE__,[NSString stringWithFormat:A, ## __VA_ARGS__]);
#else
#define TRC_DBG(A, ...)
#endif

#if (TRC_LEVEL <= 2)
#define TRC_NRM(A, ...) NSLog(@"NORMAL:%s:%d:%@", __PRETTY_FUNCTION__,__LINE__,[NSString stringWithFormat:A, ## __VA_ARGS__]);
#else
#define TRC_NRM(A, ...)
#endif

#if (TRC_LEVEL <= 3)
#define TRC_ALT(A, ...) NSLog(@"ALERT: %s:%d:%@", __PRETTY_FUNCTION__,__LINE__,[NSString stringWithFormat:A, ## __VA_ARGS__]);
#else
#define TRC_ALT(A, ...)
#endif

#if (TRC_LEVEL <= 4)
#define TRC_ERR(A, ...) NSLog(@"ERROR: %s:%d:%@", __PRETTY_FUNCTION__,__LINE__,[NSString stringWithFormat:A, ## __VA_ARGS__]);
#else
#define TRC_ERR(A, ...)
#endif

Xcode settings:

In Xcode build settings, choose "Add User-Defined Setting" (by clicking on the little cog at the bottom left of the build configuration screen), then define a new setting called GCC_PREPROCESSOR_DEFINITIONS and give it the value TRC_LEVEL=0.

The only subtlety is that Xcode doesn't know to do a clean build if you change this setting, so remember to manually do a Clean if you change it.

Ailbert answered 10/11, 2009 at 21:18 Comment(3)
Why not control trace levels by creating a new Build Configuration?Gonzalo
Yes, I already suggested that in my answer (second set of bullet points, second bullet). The "Debug" build configuration sets TRC_LEVEL=0 and "Release" build sets TRC_LEVEL=5.Ailbert
This is still pretty high on google results. Could you update with tools like crashlytics and swift frameworks like SwiftyBeaver? (I mention those two because I personally use them, but whichever)Delindadelineate
P
4

Apple automatically collects crash logs from users for you, and you can download them from iTunes connect.

If that's not enough for you, I'm not aware of a toolkit but I wouldn't want to roll something on my own, personally. It seems like too much effort to develop something robust, might raise privacy concerns, and in the end, with 100,000K apps in the app store, how many users would use your application again after discovering it was buggy?

Proto answered 3/11, 2009 at 15:40 Comment(6)
Really? Do I need to start paying closer attention to those "What's new in this release" files?Lissa
That handle some rudimentary stack and reporting.Lissa
:) I think they started doing it earlier this year. It's a bit of a pain to find though - in "Manage your applications" click "App Details" and... oh wait, the latest version of my app just came out today, so I can't look at any crash logs. So that's a negative - Apple only seems to make available the logs from the current version of your app.Proto
Ok I see this and even vaguely recall seeing it before, too. But, is that it? So, let's say I have an if-then-else-logicerror, surely it would be better to inform the user that something bad happened and record some extra information to a log, instead of simply 'crashing'? Can you somehow force a crash but somehow add some extra info to the core dump that would be helpful in debugging? Maybe the answer the answer is - "the state-of-the-art here is pretty immature, except for Apple's built-in crash uploads" I'm really hoping for something more.... clever.Lissa
Being a developer and an Iphone user, I am quite happy for an app to just crash since I rarely care why it has crashed. if its a utility app then as long as it doesnt loose my data I dont care either. I think I'd have to agree with bpapa.Phantasmal
We are using testflight.com and crittercism.com for the crash report, they provides tools to identify the problems real time. For my is better to receive notification of every crash.Macadamia
I
4

Do you know that CrashReporter for iPhone exists?

There is a repository on github which demos that code.

It has some cool features like maping the stack trace to your code and manages some git specific things like version hashes.

Intercolumniation answered 11/11, 2009 at 23:48 Comment(1)
Cool - this looks like it could be useful.Lissa
C
2

I highly recommend Robbie Hanson's CocoaLumberJack: https://github.com/robbiehanson/CocoaLumberjack

It is very flexible and powerful maybe even a bit excessive if abused. Supports different levels of logging. Logging to files can be turned on with a couple of lines of code and even be sent over the network.

Comyns answered 23/4, 2013 at 16:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.