Customizing breadcrumbs

In order to understand what happened in your application before each error, it can be helpful to leave short log statements that we call breadcrumbs. A configurable number of breadcrumbs are attached to each error report to help diagnose what events led to the error.

Automatic breadcrumbs

By default, BugSnag captures breadcrumbs for common actions and device changes, including:

  • Low memory warnings
  • Device rotation
  • Screenshot capture
  • Menu presentation
  • Table view selection
  • Window visibility changes
  • Thermal state changes
  • Non-fatal errors

This can be controlled using the enabledBreadcrumbTypes configuration option.

Capturing network requests

BugSnag can capture network requests from URLSession as breadcrumbs. These are attached to each error report to help diagnose what events led to the error:

Cocoa Network Breadcrumb screenshot

BugSnag will capture any requests from URLSession and based on the HTTP response will classify the request as success, failed or error.

To capture network breadcrumbs, install the BugsnagNetworkRequestPlugin plugin then enable it in configuration:

CocoaPods installation

Add the BugsnagNetworkRequestPlugin plugin’s pod to your Podfile:

pod 'BugsnagNetworkRequestPlugin'

Don’t forget to run pod install after updating your Podfile.

Swift Package Manager installation

In your Project Navigator, add BugsnagNetworkRequestPlugin.framework to the Frameworks, Libraries and Embedded Content section of your app’s target.

Carthage installation

Run Carthage to generate the framework to add to your project:

carthage update --use-xcframeworks --platform ios

Drag BugsnagNetworkRequestPlugin.framework from Carthage/Build to your project.

Manual installation

Select your project in the Project Navigator, then add BugsnagNetworkRequestPlugin.framework to the Frameworks, Libraries and Embedded Content section of your app’s target.

Enabling the plugin

Once the plugin is installed, configure BugSnag to start with a BugsnagNetworkRequestPlugin:

#import <BugsnagNetworkRequestPlugin/BugsnagNetworkRequestPlugin.h>

BugsnagConfiguration *config = [BugsnagConfiguration loadConfig];
[config addPlugin:[BugsnagNetworkRequestPlugin new]];
[Bugsnag startWithConfiguration:config];
import BugsnagNetworkRequestPlugin

let config = BugsnagConfiguration.loadConfig()
config.add(BugsnagNetworkRequestPlugin())
Bugsnag.start(with: config)

You can also leave network request breadcrumbs manually if you want control over which URLSessions should be logged.

Adding manual breadcrumbs

Append manual breadcrumbs with a message via the Bugsnag client:

[Bugsnag leaveBreadcrumbWithMessage:@"App loaded"];
[Bugsnag leaveBreadcrumbWithMessage:@"User clicked a button"];
Bugsnag.leaveBreadcrumb(withMessage: "App loaded")
Bugsnag.leaveBreadcrumb(withMessage: "User clicked a button")

BugSnag will keep track of the time and order of the breadcrumbs, and show them on your dashboard.

Attaching metadata

Additional data can be attached to breadcrumbs by providing the additional metadata argument. Metadata will be presented on the BugSnag dashboard alongside the breadcrumb name and type:

[Bugsnag leaveBreadcrumbWithMessage:@"Preference updated"
                           metadata:@{@"from": @"moka", @"to": @"french press"}
                            andType:BSGBreadcrumbTypeState];
Bugsnag.leaveBreadcrumb("Preference updated", 
                        metadata: ["from": "moka", "to": "french press"],
                        type: .state)

Breadcrumb “types” can be used to differentiate different types of events, such as user activity and changes in application state. See the BSGBreadcrumbType enumeration for a complete list of the breadcrumb types available. Your breadcrumbs will not be affected by the enabledBreadcrumbTypes configuration option.

Leaving network request breadcrumbs manually

To leave breadcrumbs for network requests without using BugsnagNetworkRequestPlugin, call leaveNetworkRequestBreadcrumbForTask:metrics: from your URLSessionTaskDelegate URLSession:task:didFinishCollectingMetrics: method:

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
                     didFinishCollectingMetrics:(NSURLSessionTaskMetrics *)metrics {
    [Bugsnag leaveNetworkRequestBreadcrumbForTask:task metrics:metrics];
}
func urlSession(_ session: URLSession, task: URLSessionTask,
                didFinishCollecting metrics: URLSessionTaskMetrics) {
    Bugsnag.leaveNetworkRequestBreadcrumb(task: task, metrics: metrics)
}

Capturing NSNotification events

To add breadcrumbs for every instance of a NSNotification being sent, use leaveBreadcrumbForNotificationName:

[Bugsnag leaveBreadcrumbForNotificationName:@"XYZControllerPushed"];
Bugsnag.leaveBreadcrumb(forNotificationName: "XYZControllerPushed")

This can be useful for instrumenting your own notification pipelines for notable events more quickly.

Discarding and amending breadcrumbs

You can register a callback that is executed each time a breadcrumb is captured using the addOnBreadcrumb configuration option. This can be helpful if you wish to filter out certain automatic breadcrumbs from your application or amend the data contained within them.

BugsnagConfiguration *config = [BugsnagConfiguration loadConfig];
[config addOnBreadcrumbBlock:^(BugsnagBreadcrumb *_Nonnull breadcrumb) {
    if ([breadcrumb.message isEqualToString:@"Noisy breadcrumb"]) {
        return NO; // ignore the breadcrumb
    } else {
        return YES; // capture the breadcrumb
    }
}];
[Bugsnag startWithConfiguration:config];
let config = BugsnagConfiguration.loadConfig()
config.addOnBreadcrumb { (breadcrumb) -> Bool in
    if (breadcrumb.message == "Noisy Breadcrumb") {
        return false // ignore the breadcrumb
    } else {
        return true // capture the breadcrumb
    }
}
Bugsnag.start(with: config)

Adding and removing callbacks

We recommend adding callbacks through the addOnBreadcrumb configuration option to ensure that it is registered as soon as BugSnag starts. However, the following methods are provided to allow callbacks to be added and removed whilst the application is running:

BugsnagOnBreadcrumbBlock cb = ^BOOL(BugsnagBreadcrumb *breadcrumb) { /* ... */ };
[Bugsnag addOnBreadcrumbBlock:cb];
// ...
[Bugsnag removeOnBreadcrumbBlock:cb];
func cb(breadcrumb: BugsnagBreadcrumb) -> Bool { /* ... */ }
Bugsnag.addOnBreadcrumb(block: cb)
// ...
Bugsnag.removeOnBreadcrumb(block: cb)

The BugsnagBreadcrumb class

The following information is available on the BugsnagBreadcrumb class, the representation of breadcrumb information available in a breadcrumb callback block.

property type description
message String The description of the breadcrumb
metadata Dictionary Diagnostic data relating to the breadcrumb
timestamp Date The timestamp that the breadcrumb was left
type BreadcrumbType The type of breadcrumb left