Android Crash Reporting and Error Tracking
This page is not yet available in Spanish. We are working on its translation.
If you have any questions or feedback about our current translation project,
feel free to reach out to us!Overview
Error Tracking processes errors collected from the Android SDK.
Enable Android Crash Reporting and Error Tracking to get comprehensive crash reports and error trends. With this feature, you can access:
- Aggregated Android crash dashboards and attributes
- Deobfuscated Android crash reports
- Trend analysis with Android error tracking
Your crash reports appear in Error Tracking.
Setup
If you have not set up the Android SDK yet, follow the in-app setup instructions or see the Android setup documentation.
- Add the latest version of the Android SDK to your Gradle dependencies.
- Configure your application’s
env
and variant
when initializing the SDK. - Run the Gradle tasks to upload your Proguard/R8 mapping file and NDK symbol files to Datadog to access deobfuscated stack traces.
For any given error, you can access the file path, line number, and a code snippet for each frame of the related stack trace.
Add NDK crash reporting
Your Android application may be running native code (C/C++) for performance or code reusability reasons. In order to enable NDK crash reporting, use the Datadog NDK plugin.
Add the Gradle dependency by declaring the library as a dependency in your build.gradle
file:
dependencies {
implementation "com.datadoghq:dd-sdk-android-ndk:x.x.x"
//(...)
}
Enable NDK crash collection after initializing the SDK.
Add ANR reporting
An “Application Not Responding” (ANR) is an Android-specific type of error that gets triggered when the application is unresponsive for too long.
ANRs are only reported through the SDK (not through Logs).
Report fatal ANRs
Fatal ANRs result in crashes. The application reports them when it’s unresponsive, leading to the Android OS displaying a popup dialog to the user, who chooses to force quit the app through the popup.
- In the Error Tracking page, fatal ANRs are grouped based on their similarity, which can result into several individual issues being created
- By default, Datadog catches fatal ANRs through the ApplicationExitInfo API (available since Android 30+), which can be read on the next app launch.
- In Android 29 and below, reporting on fatal ANRs is not possible.
Report non-fatal ANRs
Non-fatal ANRs may or may not have led to the application being terminated (crashing).
- In the Error Tracking page, non-fatal ANRs are grouped under a single issue due to their level of noise.
- By default, the reporting of non-fatal ANRs on Android 30+ is disabled because it would create too much noise over fatal ANRs. On Android 29 and below, however, the reporting of non-fatal ANRs is enabled by default, as fatal ANRs cannot be reported on those versions.
For any Android version, you can override the default setting for reporting non-fatal ANRs by setting trackNonFatalAnrs
to true
or false
when initializing the SDK.
Get deobfuscated stack traces
Mapping files are used to deobfuscate stack traces, which helps in debugging errors. Using a unique build ID that gets generated, Datadog automatically matches the correct stack traces with the corresponding mapping files. This ensures that regardless of when the mapping file was uploaded (either during pre-production or production builds), the correct information is available for efficient QA processes when reviewing crashes and errors reported in Datadog.
Depending on the Android Gradle plugin version, the matching of stack traces and mapping files relies on different fields:
- Version 1.13.0 uses the
build_id
field - Older versions use a combination of the
service
, version
, and variant
fields
Upload your mapping file
Note: Re-uploading a source map does not override the existing one if the version has not changed.
Add the Android Gradle Plugin to your Gradle project using the following code snippet.
// In your app's build.gradle script
plugins {
id("com.datadoghq.dd-sdk-android-gradle-plugin") version "x.y.z"
}
Create a dedicated Datadog API key and export it as an environment variable named DD_API_KEY
or DATADOG_API_KEY
. Alternatively, pass it as a task property, or if you have datadog-ci.json
file in the root of your project, it can be taken from an apiKey
property there.
Optionally, configure the plugin to upload files to the EU region by configuring the plugin in your build.gradle
script:
Run the upload task after your obfuscated APK builds:
./gradlew uploadMappingRelease
If running native code, run the NDK symbol upload task:
./gradlew uploadNdkSymbolFilesRelease
Note: If your project uses additional flavors, the plugin provides an upload task for each variant with obfuscation enabled. In this case, initialize the Android SDK with a proper variant name (the necessary API is available in versions 1.8.0
and later).
Add the Android Gradle Plugin to your Gradle project using the following code snippet.
// In your app's build.gradle script
plugins {
id("com.datadoghq.dd-sdk-android-gradle-plugin") version "x.y.z"
}
Create a dedicated Datadog API key and export it as an environment variable named DD_API_KEY
or DATADOG_API_KEY
. Alternatively, pass it as a task property, or if you have datadog-ci.json
file in the root of your project, it can be taken from an apiKey
property there.
Configure the plugin to use the EU region by adding the following snippet in your app’s build.gradle
script file:
Run the upload task after your obfuscated APK builds:
./gradlew uploadMappingRelease
If running native code, run the NDK symbol upload task:
./gradlew uploadNdkSymbolFilesRelease
Note: If your project uses additional flavors, the plugin provides an upload task for each variant with obfuscation enabled. In this case, initialize the Android SDK with a proper variant name (the necessary API is available in versions 1.8.0
and later).
List uploaded mapping files
See the RUM Debug Symbols page to view all uploaded symbols.
Plugin configuration options
There are several plugin properties that can be configured through the plugin extension. In case you are using multiple variants, you can set a property value for a specific flavor in the variant.
For example, for a fooBarRelease
variant, you can use the following configuration:
datadog {
foo {
versionName = "foo"
}
bar {
versionName = "bar"
}
fooBar {
versionName = "fooBar"
}
}
The task configuration for this variant is merged from all three flavor configurations provided in the following order:
bar
foo
fooBar
This resolves the final value for the versionName
property as fooBar
.
Property name | Description |
---|
versionName | The version name of the application (by default, the version declared in the android block of your build.gradle script). |
serviceName | The service name of the application (by default, the package name of your application as declared in the android block of your build.gradle script). |
site | The Datadog site to upload your data to (US1, US3, US5, EU1, US1_FED, or AP1). |
remoteRepositoryUrl | The URL of the remote repository where the source code was deployed. If this is not provided, this value is resolved from your Git configuration during the task execution time. |
checkProjectDependencies | This property controls if the plugin should check if the Datadog Android SDK is included in the dependencies. If not, “none” is ignored, “warn” logs a warning, and “fail” fails the build with an error (default). |
Integrate with a CI/CD pipeline
By default, the upload mapping task is independent from other tasks in the build graph. Run the task manually when you need to upload mapping.
If you want to run this task in a CI/CD pipeline, and the task is required as part of the build graph, you can set the upload task to run after the mapping file is generated.
For example:
tasks["minify${variant}WithR8"].finalizedBy { tasks["uploadMapping${variant}"] }
Limitations
File sizing
Mapping files are limited to 500 MB. If your project has a mapping file larger than this, use one of the following options to reduce the file size:
Mapping files are limited to 50 MB. If your project has a mapping file larger than this, use one of the following options to reduce the file size:
- Set the
mappingFileTrimIndents
option to true
. This reduces your file size by 5%, on average. - Set a map of
mappingFilePackagesAliases
: This replaces package names with shorter aliases. Note: Datadog’s stacktrace uses the same alias instead of the original package name, so it’s better to use this option for third party dependencies.
datadog {
mappingFileTrimIndents = true
mappingFilePackageAliases = mapOf(
"kotlinx.coroutines" to "kx.cor",
"com.google.android.material" to "material",
"com.google.gson" to "gson",
"com.squareup.picasso" to "picasso"
)
}
Collection
When looking at RUM Crash Reporting behaviors for Android, consider the following:
- The crash can only be detected after the SDK is initialised. Given this, the recommendation is to initialize the SDK as soon as possible in your application’s
onCreate
method. - RUM crashes must be attached to a RUM view. If a crash occurs before a view is visible (typically an Activity or Fragment in an
onResume
state), or after the app is sent to the background by the end-user navigating away from it, the crash is muted and isn’t reported for collection. To mitigate this, use the trackBackgroundEvents()
method in your RumConfiguration
builder. - Only crashes that occur in sampled sessions are kept, meaning if a session sampling rate is not 100%, some will not be reported.
Test your implementation
To verify your Android Crash Reporting and Error Tracking configuration, you need to trigger a crash in your application and confirm that the error appears in Datadog.
To test your implementation:
Run your application on an Android emulator or a real device.
Execute some code containing an error or crash. For example:
fun onEvent() {
throw RuntimeException("Crash the app")
}
After the crash happens, restart your application and wait for the Android SDK to upload the crash report in Error Tracking.
Further Reading
Más enlaces, artículos y documentación útiles: