Configuration options

The Bugsnag client object has many configuration options that can be set to customize the content of events and sessions and how they are sent.

This documentation is for version 5+ of the BugSnag Android notifier. If you are using older versions, we recommend upgrading to the latest release using our Upgrade guide. Documentation for the previous release can be found on our legacy pages.

Setting configuration options

Most configuration options can be set in your App Manifest (AndroidManifest.xml):

<application ...>
  <meta-data android:name="com.bugsnag.android.API_KEY"
             android:value="your-api-key-here"/>
</application>

With your settings in the app manifest file, BugSnag can simply be started using:

Bugsnag.start(this);
Bugsnag.start(this)

Alternatively, configuration options can be specified in code by creating a Configuration object and passing it into Bugsnag.start:

Configuration config = Configuration.load(this);
config.setAppVersion("1.0.0-alpha");
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.appVersion = "1.0.0-alpha"
Bugsnag.start(this, config)

Configuration.load uses your app manifest to set initial configuration values, allowing you to augment and override the values before they are used to start BugSnag. You can use the Configuration constructor to avoid using the manifest file.

To set different configuration values based on build variants or product flavors, see Customizing by build setting.

Available options

addFeatureFlag

Declare a single feature flag or experiment with variant as an optional second parameter.

Configuration config = Configuration.load(this);
config.addFeatureFlag("Checkout button color", "Blue");
config.addFeatureFlag("New checkout flow");
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.addFeatureFlag("Checkout button color", "Blue")
config.addFeatureFlag("New checkout flow")
Bugsnag.start(this, config)

See the Feature flags & experiments guide for more information.

addFeatureFlags

Declare multiple feature flags or experiments.

Configuration config = Configuration.load(this);
config.addFeatureFlags(Arrays.asList(
  new FeatureFlag("Checkout button color", "Blue"),
  new FeatureFlag("another example", "experiment 2"),
  new FeatureFlag("New checkout flow")
));
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.addFeatureFlags(listOf(
  FeatureFlag("Checkout button color", "Blue"),
  FeatureFlag("another example", "experiment 2"),
  FeatureFlag("New checkout flow")
))
Bugsnag.start(this, config)

See the Feature flags & experiments guide for more information.

addMetadata

Set diagnostic metadata that you want to send with all captured events – see Customizing error reports for more information.

Configuration config = Configuration.load(this);
config.addMetadata("account", "name", "Acme Co.");
config.addMetadata("basket", new HashMap<String, Object>() {{
  put("delivery", "express");
  put("sale", "spring");
}});
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.addMetadata("account", "name", "Acme Co.")
config.addMetadata("basket", hashMapOf(
  "delivery" to "express",
  "sale" to "spring"
))
Bugsnag.start(this, config)

For NDK errors, the event metadata and the metadata on each breadcrumb will be restricted to 128 entries and 63-character keys. Any additional data will be truncated.

addOnBreadcrumb

Add callbacks to modify or discard breadcrumbs before they are recorded — see Customizing breadcrumbs for more information.

Configuration config = Configuration.load(this);
config.addOnBreadcrumb(new OnBreadcrumbCallback() {
    @Override
    public boolean onBreadcrumb(@NonNull Breadcrumb breadcrumb) {
        if (breadcrumb.getMessage().equals("Noisy breadcrumb")) {
            return false; // ignore the breadcrumb
        } else {
            return true; // capture the breadcrumb
        }
    }
});
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.addOnBreadcrumb(OnBreadcrumbCallback { breadcrumb ->
    if (breadcrumb.message == "Noisy breadcrumb") {
        false // ignore the breadcrumb
    } else {
        true // capture the breadcrumb
    }
}
Bugsnag.start(this, config)

addOnError

Add callbacks to modify or discard error events before they are sent to BugSnag — see Customizing error reports for more information.

addOnSend

Add callbacks to modify or discard error events before they are sent to BugSnag, including events for which callbacks cannot be invoked at the time of the error, like native C/C++ crashes — see Customizing error reports for more information.

Use OnSendCallback to modify or cancel error reports immediately prior to report delivery. Report delivery may not be during the same app launch as the error occurred, as the app may be offline when the error occurs or terminate immediately in the case of crashes from native C/C++ code. Avoid attaching additional information to a report that does not relate to the crashed session.

Configuration config = Configuration.load(this);
config.addOnSend(new OnSendCallback() {
    @Override
    public boolean onSend(Event event) {
        event.addMetadata("account", "name", "Acme Co.");
        event.addMetadata("account", "paying_customer", true);

        // Return `false` if you'd like to stop this error being reported
        return true;
    }
});
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.addOnSend(OnSendCallback { event ->
    event.addMetadata("account", "name", "Acme Co.")
    event.addMetadata("account", "paying_customer", true)

    // Return `false` if you'd like to stop this error being reported
    true
})
Bugsnag.start(this, config)

addOnSession

Add callbacks to modify or discard sessions before they are sent to BugSnag — see Capturing sessions for more information.

Configuration config = Configuration.load(this);
config.addOnSession(new OnSessionCallback() {
    @Override
    public boolean onSession(Session session) {
        String userId = getMyUserIdentifier(); // a custom user resolver
        session.setUser(userId, null, null);
        return true; // Return false to discard
    }
});
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.addOnSession(OnSessionCallback { session ->
    val userId = getMyUserIdentifier() // a custom user resolver
    session.setUser(userId, null, null)
    true // Return false to discard
}
Bugsnag.start(this, config)

addPlugin

Provides a plugin that enhances BugSnag’s functionality. For example, capturing network breadcrumbs requires the BugsnagOkHttpPlugin (see our Customizing breadcrumbs guide):

BugsnagOkHttpPlugin bugsnagPlugin = new BugsnagOkHttpPlugin();
Configuration config = Configuration.load(this);
config.addPlugin(bugsnagPlugin);
Bugsnag.start(this, config);
val bugsnagPlugin = BugsnagOkHttpPlugin()
Bugsnag.start(this, Configuration.load(this).apply {
    addPlugin(bugsnagPlugin)
})

apiKey

The API key used for events sent to BugSnag.

Configuration config = Configuration.load(this);
config.setApiKey("your-other-api-key-here");
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.apiKey = "your-other-api-key-here"
Bugsnag.start(this, config)

Or in the app manifest:

<application ...>
  <meta-data android:name="com.bugsnag.android.API_KEY"
             android:value="your-api-key-here"/>
</application>

You can find your API key in Project Settings from your BugSnag dashboard.

When using the BugSnag Gradle plugin the API key cannot be set by resource values. Instead it should be set directly in the manifest or using manifest placeholders – see Customizing by build setting.

appType

If your app’s codebase contains different entry-points/processes, but reports to a single BugSnag project, you might want to add information denoting the type of process the error came from.

This information can be used in the dashboard to filter errors and to determine whether an error is limited to a subset of appTypes.

Configuration config = Configuration.load(this);
config.setAppType("lite");
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.appType = "lite"
Bugsnag.start(this, config)

Or in the app manifest:

<application ...>
  <meta-data android:name="com.bugsnag.android.APP_TYPE"
             android:value="lite"/>
</application>

appVersion

The version of the application. This is really useful for finding out when errors are introduced and fixed. Additionally BugSnag can re-open closed errors if a later version of the app has a regression.

Bugsnag will automatically set the version from the versionName field in your app manifest file. If you’d like to override this you can set appVersion on Configuration:

Configuration config = Configuration.load(this);
config.setAppVersion("1.0.0-alpha");
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.appVersion = "1.0.0-alpha"
Bugsnag.start(this, config)

Or in the app manifest:

<application ...>
  <meta-data android:name="com.bugsnag.android.APP_VERSION"
             android:value="1.0.0-alpha"/>
</application>

attemptDeliveryOnCrash

Whether BugSnag should try to send crashing errors prior to app termination.

Configuration config = Configuration.load(this);
config.setAttemptDeliveryOnCrash(false);
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.attemptDeliveryOnCrash = false
Bugsnag.start(this, config)

Delivery will only be attempted for uncaught Java/Kotlin exceptions and errors, and while in progress will block the crashing thread for up to 3 seconds. Delivery should be considered unreliable due to the necessary short timeout and unreliable state of the app following an exception. If delivery fails prior to termination, it will be reattempted at next launch (the default behavior).

This feature is disabled by default and its use is discouraged because it:

  • may cause additional Application Not Responding (ANR) errors, during the delivery attempt
  • will result in duplicate error reports in your dashboard if the app terminates before the report can be confirmed as sent
  • may prevent other crash reporters from detecting or reporting a crash.

autoDetectErrors

By default, we will automatically notify BugSnag of any uncaught errors that we capture. Use this flag to disable all automatic detection.

Configuration config = Configuration.load(this);
config.setAutoDetectErrors(false);
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.autoDetectErrors = false
Bugsnag.start(this, config)

Or in the app manifest:

<application ...>
  <meta-data android:name="com.bugsnag.android.AUTO_DETECT_ERRORS"
             android:value="false"/>
</application>

Setting autoDetectErrors to false will disable all automatic errors, regardless of the error types enabled by enabledErrorTypes.

autoTrackSessions

By default, BugSnag will automatically capture and report session information from your application. Use this flag to disable all automatic reporting.

Configuration config = Configuration.load(this);
config.setAutoTrackSessions(false);
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.autoTrackSessions = false
Bugsnag.start(this, config)

Or in the app manifest:

<application ...>
  <meta-data android:name="com.bugsnag.android.AUTO_TRACK_SESSIONS"
             android:value="false"/>
</application>

If you want control over what is deemed a session, you can switch off the automatic session tracking option and manage the session manually. See Capturing sessions for more information.

buildUUID

The unique identifier for the build of the application. This value is only required if you are using symbol mapping with manual symbol file uploads (not using the BugSnag Android Gradle Plugin)

Set this in the app manifest:

<application ...>
  <meta-data android:name="com.bugsnag.android.BUILD_UUID"
             android:value="502b7f1a-ea99-4e93-9549-271dad827192"/>
</application>

clearFeatureFlag

Remove a single feature flag or experiment.

Configuration config = Configuration.load(this);
config.clearFeatureFlag("Checkout button color");
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.clearFeatureFlag("Checkout button color")
Bugsnag.start(this, config)

See the Feature flags & experiments guide for more information.

clearFeatureFlags

Remove all feature flags and experiments.

Configuration config = Configuration.load(this);
config.clearFeatureFlags();
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.clearFeatureFlags()
Bugsnag.start(this, config)

See the Feature flags & experiments guide for more information.

clearMetadata

Clears diagnostic metadata from being sent in subsequent events – see Customizing error reports for more information.

Configuration config = Configuration.load(this);
config.clearMetadata("account");
// or
config.clearMetadata("account", "name");
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.clearMetadata("account")
// or
config.clearMetadata("account", "name")
Bugsnag.start(this, config)

context

The “context” is a string that indicates what the user was doing when an error occurs and is given high visual prominence in the dashboard. Set an initial context that you want to send with events – see Setting context for more information.

Configuration config = Configuration.load(this);
config.setContext("InitialTutorialStep");
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.context = "InitialTutorialStep"
Bugsnag.start(this, config)

delivery

The Delivery implementation used to make network calls to the BugSnag Error Reporting and Sessions API.

This may be useful if you have requirements such as certificate pinning and rotation, which are not supported by the default implementation.

Configuration config = Configuration.load(this);
config.setDelivery(new CertPinnedDelivery());
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.delivery = CertPinnedDelivery()
Bugsnag.start(this, config)

To provide custom delivery functionality, create a class which implements the Delivery interface. Please note that request bodies must match the structure specified in the Error Reporting and Sessions API documentation.

You can use the return type from the deliver functions to control the strategy for retrying the transmission at a later date. If DeliveryStatus.UNDELIVERED is returned, the notifier will automatically cache the payload and trigger delivery later on. Otherwise, if either DeliveryStatus.DELIVERED or DeliveryStatus.FAILURE is returned the notifier will removed any cached payload and no further delivery will be attempted.

For example, if the device has no network connectivity, it may make sense to store the report and send it later:

if (!hasNetworkConnection) {
    return DeliveryStatus.UNDELIVERED;
}
if (!hasNetworkConnection) {
    return DeliveryStatus.UNDELIVERED
}

Custom Delivery Example

A full example of a custom Delivery which uses certificate pinning is provided below.

Pinning certificates with OkHttp3
/**
 * A custom API client which uses Square's OkHttp3 Library to pin certificates.
 */
class CertPinnedApiClient implements Delivery {

    OkHttpClient okHttpClient;

    // The public key hash(es) for your cert
    // can be found by following OkHttp3 instructions:
    // https://square.github.io/okhttp/3.x/okhttp/okhttp3/CertificatePinner.html
    CertPinnedApiClient() {
        String hash1 = "sha256/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX=";
        String hash2 = "sha256/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX=";

        CertificatePinner certificatePinner = new CertificatePinner.Builder()
            .add("mywebsite.com", hash1) // expires in 2019
            .add("mywebsite.com", hash2) // expires in 2020
            .build();

        okHttpClient = new OkHttpClient.Builder()
            .certificatePinner(certificatePinner)
            .build();
    }

    String getJsonBody(EventPayload payload) {
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            JsonStream jsonStream = new JsonStream(new PrintWriter(baos));
            payload.toStream(jsonStream);
            jsonStream.flush();
            return baos.toString("UTF-8");
        } catch (IOException e) {
            throw new RuntimeException("Failed to generate request", e);
        }
    }

    @Override
    public void deliver(EventPayload payload, DeliveryParams deliveryParams) {
        try {
            MediaType mediaType = MediaType.parse("application/json");
            Request request = new Request.Builder()
                .headers(Headers.of(deliveryParams.getHeaders())) // add error API headers
                .url(deliveryParams.getEndpoint()) // use error API endpoint
                .post(RequestBody.create(mediaType, getJsonBody(payload)))
                .build();
            Response response = okHttpClient.newCall(request).execute();
            response.isSuccessful() ? return DeliveryStatus.DELIVERED : DeliveryStatus.FAILURE;
        } catch (IOException e) {
            return DeliveryStatus.UNDELIVERED;
        }
    }

    @Override
    public void deliver(SessionPayload payload, DeliveryParams deliveryParams) {
        // implement as per event payload
    }
}
/**
 * A custom API client which uses Square's OkHttp3 Library to pin certificates.
 */
class CertPinnedApiClient : Delivery {

    var okHttpClient: OkHttpClient

    // The public key hash(es) for your cert
    // can be found by following OkHttp3 instructions:
    // https://square.github.io/okhttp/3.x/okhttp/okhttp3/CertificatePinner.html
    init {
        val hash1 = "sha256/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX="
        val hash2 = "sha256/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX="

        val certificatePinner = CertificatePinner.Builder()
            .add("mywebsite.com", hash1) // expires in 2019
            .add("mywebsite.com", hash2) // expires in 2020
            .build()

        okHttpClient = OkHttpClient.Builder()
            .certificatePinner(certificatePinner)
            .build()
    }

    fun getJsonBody(payload: EventPayload): String {
        try {
            val baos = ByteArrayOutputStream()
            val jsonStream = JsonStream(PrintWriter(baos))
            report.toStream(jsonStream)
            jsonStream.flush()
            return baos.toString("UTF-8")
        } catch (e: IOException) {
            throw RuntimeException("Failed to generate request", e)
        }
    }

    override fun deliver(payload: EventPayload, deliveryParams: DeliveryParams) {
        try {
            val mediaType = MediaType.parse("application/json")
            val request = Request.Builder()
                .headers(Headers.of(deliveryParams.headers)) // add error API headers
                .url(deliveryParams.endpoint) // use error API endpoint
                .post(RequestBody.create(mediaType, getJsonBody(payload)))
                .build()
            val response = okHttpClient.newCall(request).execute()
            response.isSuccessful() ? return DeliveryStatus.DELIVERED : DeliveryStatus.FAILURE;
        } catch (e: IOException) {
            return DeliveryStatus.UNDELIVERED
        }
    }

    override fun deliver(payload: SessionPayload, deliveryParams: DeliveryParams) {
        // implement as per event payload
    }
}

discardClasses

Allows you to specify which events should be automatically discarded based on their errorClass.

The library performs an exact match against the canonical class name.

Configuration config = Configuration.load(this);
config.setDiscardClasses(new HashSet<Pattern>() {{
    add(Pattern.compile("java.net.UnknownHostException", Pattern.LITERAL));
    add(Pattern.compile("com\\.example\\.ignored.*"));
}});
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.discardClasses = setOf(
    Pattern.compile("java.net.UnknownHostException", Pattern.LITERAL),
    Pattern.compile("com\\.example\\.ignored.*")
)
Bugsnag.start(this, config)

Or in the app manifest:

<application ...>
  <meta-data android:name="com.bugsnag.android.DISCARD_CLASSES"
             android:value="com.domain.ClassName,com.domain.SecondClassName"/>
</application>

enabledBreadcrumbTypes

By default BugSnag will automatically add breadcrumbs for common application events whilst your application is running. Set this option to configure which of these are enabled and sent to BugSnag.

Configuration config = Configuration.load(this);
config.setEnabledBreadcrumbTypes(new HashSet<BreadcrumbType>() {{
    add(BreadcrumbType.NAVIGATION);
    add(BreadcrumbType.REQUEST);
}});
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.enabledBreadcrumbTypes = setOf(BreadcrumbType.NAVIGATION, BreadcrumbType.REQUEST)
Bugsnag.start(this, config)

Automatically captured breadcrumbs can be disabled by providing an empty set in enabledBreadcrumbTypes.

Configuration config = Configuration.load(this);
config.setEnabledBreadcrumbTypes(new HashSet<BreadcrumbType>());
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.enabledBreadcrumbTypes = emptySet()
Bugsnag.start(this, config)

The following automatic breadcrumb types can be enabled:

Captured errors

Error breadcrumbs (BreadcrumbType.ERROR) are left when an error event is sent to the Bugsnag API.

Console messages (React Native only)

Log breadcrumbs (BreadcrumbType.LOG) are left for each message logged to the console.

Navigation breadcrumbs (BreadcrumbType.NAVIGATION) are left for Activity Lifecycle events to track the user’s journey in the app.

Network Requests

Request breadcrumbs (BreadcrumbType.REQUEST) are left when a network request is made, and the bugsnag-plugin-android-okhttp is enabled.

State changes

State breadcrumbs (BreadcrumbType.STATE) are left for system broadcast events. For example: battery warnings, airplane mode, etc. See Automatically captured data for more information.

User interaction

User breadcrumbs (BreadcrumbType.USER) are left when the user performs certain system operations. See Automatically captured data for more information.

enabledErrorTypes

BugSnag will automatically detect different types of error in your application. Set this option if you wish to control exactly which types are enabled.

Configuration config = Configuration.load(this);
config.getEnabledErrorTypes().setAnrs(true);
config.getEnabledErrorTypes().setNdkCrashes(true);
config.getEnabledErrorTypes().setUnhandledExceptions(true);
config.getEnabledErrorTypes().setUnhandledRejections(true); // React Native only
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.enabledErrorTypes.anrs = true
config.enabledErrorTypes.ndkCrashes = true
config.enabledErrorTypes.unhandledExceptions = true
config.enabledErrorTypes.unhandledRejections = true // React Native only
Bugsnag.start(this, config)

Setting autoDetectErrors to false will disable all automatic errors, regardless of the error types enabled by enabledErrorTypes.

enabledReleaseStages

By default, BugSnag will be notified of events that happen in any releaseStage. Set this option if you would like to change which release stages notify BugSnag.

Configuration config = Configuration.load(this);
config.setEnabledReleaseStages(new HashSet<String>() {{
    add("production");
    add("development");
    add("testing");
}});
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.enabledReleaseStages = setOf("production", "development", "testing")
Bugsnag.start(this, config)

Or in the app manifest:

<application ...>
  <meta-data android:name="com.bugsnag.android.ENABLED_RELEASE_STAGES"
             android:value="production,development,testing"/>
</application>

endpoints

By default we will send error reports to notify.bugsnag.com and sessions to sessions.bugsnag.com.

If you are using BugSnag On-premise you’ll need to set these to your Event Server and Session Server endpoints. If the notify endpoint is set but the sessions endpoint is not, session tracking will be disabled automatically to avoid leaking session information outside of your server configuration, and a warning will be logged.

Configuration config = Configuration.load(this);
config.setEndpoints(new EndpointConfiguration("https://notify.example.com", "https://sessions.example.com"));
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.endpoints = EndpointConfiguration("https://notify.example.com", "https://sessions.example.com")
Bugsnag.start(this, config)

Or in the app manifest:

<application ...>
  <meta-data android:name="com.bugsnag.android.ENDPOINT_NOTIFY"
             android:value="https://notify.bugsnag.com"/>
  <meta-data android:name="com.bugsnag.android.ENDPOINT_SESSIONS"
             android:value="https://sessions.bugsnag.com"/>
</application>

launchDurationMillis

The amount of time (in milliseconds) after starting BugSnag that should be considered part of the app’s launch.

By default this value is 5000 milliseconds.

Configuration config = Configuration.load(this);
config.setLaunchDurationMillis(0);
Bugsnag.start(this, config);

// Once your app has finished launching
Bugsnag.markLaunchCompleted();
val config = Configuration.load(this)
config.launchDurationMillis = 0
Bugsnag.start(this, config)

// Once your app has finished launching
Bugsnag.markLaunchCompleted()

Or in the app manifest:

<application ...>
  <meta-data android:name="com.bugsnag.android.LAUNCH_DURATION_MILLIS"
             android:value="0"/>
</application>

Events that occur during app launch will have their app.isLaunching property set to true.

Setting this to 0 will cause BugSnag to consider the app to be launching until Bugsnag.markLaunchCompleted() has been called.

logger

By default, the notifier’s log messages will be logged using the android.util.Log with a Bugsnag tag unless the release stage is “production”.

To override this behavior, an alternative instance can be provided that implements the com.bugsnag.android.Logger interface:

Configuration config = Configuration.load(this);
config.setLogger(new Logger() {
    void e(String msg) {
        // error logging code
    }
    void e(String msg, Throwable throwable) {
        // error logging code
    }
    // ... warning, info and debug
});
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.logger = object: Logger {
    override fun e(msg: String) {
        // error logging code
    }
    override fun e(msg: String, throwable: Throwable) {
        // error logging code
    }
    // ... warning, info and debug
}
Bugsnag.start(this, config)

maxBreadcrumbs

Sets the maximum number of breadcrumbs which will be stored. Once the threshold is reached, the oldest breadcrumbs will be deleted.

By default, 100 breadcrumbs are stored; this can be amended up to a maximum of 500.

Configuration config = Configuration.load(this);
config.setMaxBreadcrumbs(75);
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.maxBreadcrumbs = 75
Bugsnag.start(this, config)

Or in the app manifest:

<application ...>
  <meta-data android:name="com.bugsnag.android.MAX_BREADCRUMBS"
             android:value="75"/>
</application>

For NDK events the maximum number of breadcrumbs is fixed at the default of 50 and cannot be amended.

If a payload is greater than the 1MB upload limit, when possible breadcrumbs will be dropped (oldest first) until the size is reduced below the limit.

maxPersistedEvents

Sets the maximum number of events which will be stored on disk for sending later at times when there is no internet connection available. Once the threshold is reached, the oldest events will be deleted.

By default, 32 events are stored.

Configuration config = Configuration.load(this);
config.setMaxPersistedEvents(50);
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.maxPersistedEvents = 50
Bugsnag.start(this, config)

Or in the app manifest:

<application ...>
  <meta-data android:name="com.bugsnag.android.MAX_PERSISTED_EVENTS"
             android:value="50"/>
</application>

maxPersistedSessions

Sets the maximum number of sessions which will be stored on disk for sending later at times when there is no internet connection available. Once the threshold is reached, the oldest sessions will be deleted.

By default, 128 sessions are stored.

Configuration config = Configuration.load(this);
config.setMaxPersistedSessions(50);
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.maxPersistedSessions = 50
Bugsnag.start(this, config)

Or in the app manifest:

<application ...>
  <meta-data android:name="com.bugsnag.android.MAX_PERSISTED_SESSIONS"
             android:value="50"/>
</application>

maxReportedThreads

Sets the maximum number of threads that will be captured and sent with an error event.

Configuration config = Configuration.load(this);
config.setMaxReportedThreads(100);
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.maxReportedThreads = 100
Bugsnag.start(this, config)

The default maximum number of threads that will be captured is 200.

maxStringValueLength

The maximum length of a string in metadata. To help avoid excessive event payload sizes, any strings exceeding this length will be truncated.

This limit defaults to 10,000 characters.

Configuration config = Configuration.load(this);
config.setMaxStringValueLength(5000);
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.maxStringValueLength = 5000
Bugsnag.start(this, config)

persistenceDirectory

Sets the directory where BugSnag data, such as event and session payloads, are cached on disk. User information is also persisted here if persistUser is true.

Configuration config = Configuration.load(this);
config.setPersistenceDirectory(new File("/my-custom-dir"));
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.persistenceDirectory = File("/my-custom-dir")
Bugsnag.start(this, config)

The default directory for this property is Android’s cache directory.

If you change the value of persistenceDirectory between application launches, no attempt will be made to migrate data persisted from the original location. This may result in events and sessions not being delivered to BugSnag.

persistUser

Set whether or not BugSnag should persist user information between application launches.

By default persistUser is set to true. To disable this behavior:

Configuration config = Configuration.load(this);
config.setPersistUser(false);
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.persistUser = false
Bugsnag.start(this, config)

Or in the app manifest:

<application ...>
  <meta-data android:name="com.bugsnag.android.PERSIST_USER"
             android:value="false"/>
</application>

If enabled then any user information set will be re-used until the user information is removed manually by calling Bugsnag.setUser with null arguments.

projectPackages

Sets which package names BugSnag should consider as a part of the running application. We mark stacktrace lines as in-project if they originate from any of these packages and this allows us to improve the visual display of the stacktrace on the dashboard.

Configuration config = Configuration.load(this);
config.setProjectPackages(new HashSet<String>() {{
    add("com.company.package1");
    add("com.company.package2");
}});
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.projectPackages = setOf("com.company.package1", "com.company.package2")
Bugsnag.start(this, config)

Or in the app manifest:

<application ...>
  <meta-data android:name="com.bugsnag.android.PROJECT_PACKAGES"
             android:value="com.company.package1,com.company.package2"/>
</application>

By default, projectPackages is set to be the package you called Bugsnag.start from.

redactedKeys

Sets which values should be removed from any metadata before sending them to BugSnag. Use this if you want to ensure you don’t transmit sensitive data such as passwords and credit card numbers.

Any property whose key matches a redacted key will be filtered and replaced with [REDACTED]. By default, any key that contains “password” will be redacted. Be aware that if you set this configuration option, it will replace the default, so you may want to replace “password” in your own set if you want to filter that.

redactedKeys is a set of java.util.regex.Pattern:

Configuration config = Configuration.load(this);
config.setRedactedKeys(new HashSet<Pattern>() {{
    add(Pattern.compile(".*password.*"));
    add(Pattern.compile(".*secret.*"));
    add(Pattern.compile("credit_card_number", Pattern.LITERAL));
}});
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.redactedKeys = setOf(
    Pattern.compile(".*password.*"),
    Pattern.compile(".*secret.*"),
    Pattern.compile("credit_card_number", Pattern.LITERAL)
)
Bugsnag.start(this, config)

Or in the app manifest:

<application ...>
  <meta-data android:name="com.bugsnag.android.REDACTED_KEYS"
             android:value=".*password.*,.*secret.*"/>
</application>

By default, redactedKeys is set to .password.

redactedKeys changed from a set of strings to Patterns in v6.x of the SDK.

releaseStage

Allows you to distinguish between errors that happen in different stages of the application release process (development, production, etc).

This is automatically configured by the notifier to be “production”, unless the app is built with debug enabled in which case it will be set to “development”. If you wish to override this, you can do so by setting the releaseStage property manually:

Configuration config = Configuration.load(this);
config.setReleaseStage("testing");
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.releaseStage = "testing"
Bugsnag.start(this, config)

Or in the app manifest:

<application ...>
  <meta-data android:name="com.bugsnag.android.RELEASE_STAGE"
             android:value="testing"/>
</application>

You can control whether events are sent for specific release stages using the enabledReleaseStages option.

sendLaunchCrashesSynchronously

Determines whether launch crashes should be sent synchronously whilst BugSnag starts.

If this option is enabled and the previous run terminated due to a crash during app launch, BugSnag will block the calling thread when it starts for up to 2 seconds while the crash report is sent.

This behavior is enabled by default.

Configuration config = Configuration.load(this);
// To prevent sending launch crashes synchronously
config.setSendLaunchCrashesSynchronously(false);
Bugsnag.start(this, config);
val config = Configuration.load(this)
// To prevent sending launch crashes synchronously
config.sendLaunchCrashesSynchronously = false
Bugsnag.start(this, config)

Or in the app manifest:

<application ...>
  <meta-data android:name="com.bugsnag.android.SEND_LAUNCH_CRASHES_SYNCHRONOUSLY"
             android:value="true"/>
</application>

sendThreads

Controls whether we should capture and serialize the state of all threads at the time of an exception.

By default sendThreads is set to Thread.ThreadSendPolicy.ALWAYS. This can be set to Thread.ThreadSendPolicy.NEVER to disable or Thread.ThreadSendPolicy.UNHANDLED_ONLY to only do so for unhandled errors.

Configuration config = Configuration.load(this);
config.setSendThreads(Thread.ThreadSendPolicy.ALWAYS);
// alternatively: config.setSendThreads(Thread.ThreadSendPolicy.UNHANDLED_ONLY);
//            or: config.setSendThreads(Thread.ThreadSendPolicy.NEVER);
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.sendThreads = Thread.ThreadSendPolicy.ALWAYS
// alternatively: config.sendThreads = Thread.ThreadSendPolicy.UNHANDLED_ONLY
//            or: config.sendThreads = Thread.ThreadSendPolicy.NEVER
Bugsnag.start(this, config)

Or in the app manifest:

<application ...>
  <meta-data android:name="com.bugsnag.android.SEND_THREADS"
             android:value="ALWAYS"/>
  <!-- alternatively: android:value="UNHANDLED_ONLY" -->
  <!--            or: android:value="NEVER"          -->
</application>

setUser

Set global user data that you want to send with all captured events – see Adding user data for more information.

Configuration config = Configuration.load(this);
config.setUser("3", "bugs.nag@bugsnag.com", "Bugs Nag");
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.setUser("3", "bugs.nag@bugsnag.com", "Bugs Nag")
Bugsnag.start(this, config)

telemetry

Internal errors

Internal errors are sent when an error is detected within BugSnag, for example when a crash report cannot be processed.

To prevent these from being sent:

Configuration config = Configuration.load(this);
configuration.getTelemetry().remove(Telemetry.INTERNAL_ERRORS);
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.telemetry.remove(Telemetry.INTERNAL_ERRORS)
Bugsnag.start(this, config)

Usage

Usage telemetry helps us improve BugSnag by providing information on how you are configuring the SDK. We record:

  • when your config differs from the defaults
  • BugSnag functionality utilized

We collect only bools, ints and enums. We do not collect any information personal to you or your users. The information is sent as part of error events; there is no additional network call made.

To prevent this from being sent:

Configuration config = Configuration.load(this);
configuration.getTelemetry().remove(Telemetry.USAGE);
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.telemetry.remove(Telemetry.USAGE)
Bugsnag.start(this, config)

versionCode

We’ll automatically pull the versionCode field from your app manifest file. If you’d like to override this you can set this option manually.

Configuration config = Configuration.load(this);
config.setVersionCode(55);
Bugsnag.start(this, config);
val config = Configuration.load(this)
config.versionCode = 55
Bugsnag.start(this, config)

Or in the app manifest:

<application ...>
  <meta-data android:name="com.bugsnag.android.VERSION_CODE"
             android:value="55"/>
</application>

Customizing by build setting

Manifest placeholders

BugSnag can be set up to use different configuration values for different build variants, by using manifest placeholders in your app’s build.gradle script.

android {
    defaultConfig {
        manifestPlaceholders = [
            bugsnagAppType: "lite"
        ]
    }
    productFlavors {
        pro {
            manifestPlaceholders = [
                // override defaultConfig values here
                bugsnagAppType: "pro"
            ]
        }
    }
}

For all the values you wish to configure, provide a meta-data element at the bottom of your app manifest file (AndroidManifest.xml):

<application ...>
    <meta-data android:name="com.bugsnag.android.APP_TYPE" android:value="${bugsnagAppType}"/>
</application>

Using Resource values

Gradle resource values allow you to share custom fields and values between build files and app code.

When using the BugSnag Gradle plugin the API key configuration option cannot be set by resource values. Instead it should be set directly in the manifest or using manifest placeholders – see above.

For example, to set a release stage in your build configuration, set a resource value in your Gradle file:

def bugsnag_release_stage = project.hasProperty("bugsnag-release-stage")
    ? project.property("bugsnag-release-stage") : "staging"

buildTypes {
    release {
        resValue("string", "bugsnag_release_stage", "${bugsnag_release_stage}")
    }
}

To load the value automatically when BugSnag starts, set a placeholder in your app manifest for the value:

<application ...>
    <meta-data android:name="com.bugsnag.android.RELEASE_STAGE"
     android:value="@string/bugsnag_release_stage"/>
</application>

Properties can also be loaded at runtime if needed (though not required if placeholders are set in app manifest):

Configuration config = new Configuration(getString(R.string.bugsnag_release_stage));
Bugsnag.start(this, config);
val config = Configuration(getString(R.string.bugsnag_release_stage))
Bugsnag.start(this, config)