Configure Session Replay on crashes for Android
This page describes how to enable and customize Session Replay on crashes for your Android apps.
Session Replay on crashes visually recreates the last user actions before a crash happened in your mobile application. It allows you to reproduce the issue that your users experienced so that you have the full context to understand what has happened and why.
All technical information is available at JavaDoc for Dynatrace Session Replay.
Prerequisites
Make sure that your system meets the following requirements:
- Dynatrace version 1.245+
- OneAgent for Android version 8.245+
-
Real User Monitoring enabled for your application
-
Active Dynatrace Digital Experience Monitoring license
-
The web UI URL has a trusted certificate
-
Dynatrace Managed only Secondary disk configured to store user session data
Known limitations and issues
Technical limitations
- Android 5.0+ (API level 21+) is supported.
- Android Gradle plugin 4.0+ is supported.
For Android Gradle plugin 4.0 and 4.1, you need to change the compile option to Java 8.
- Jetpack Compose is not supported.
- Only AndroidX support libraries are supported. Classes such as
Activity
orFragment
incom.android.support
are not supported. - The recording of a navigation drawer usage and visibility changes is not currently supported, but you can instrument these events manually.
- Session Replay is not available for Cordova, React Native, Flutter, or Xamarin.
- For a hybrid app, Session Replay on crashes is supported only for the native part of the app. Session Replay is not supported for the browser part of a hybrid app.
- We recommend that you not use other crash reporting tools together with Dynatrace Session Replay.
- Session Replay can capture only certain events. However, if you need to track a specific view or event that is not supported by default, you can capture a custom event.
- You can play back the user sessions recorded with Session Replay only in certain browsers.
See Technical restrictions for Session Replay for web applications for more information.
Known issues
- Fragments with in-out animations can cause problems, especially when animations are short.
- Floating action buttons can cause data masking issues.
Enable Session Replay on crashes
If you haven't done so already, complete all steps described in the instrumentation wizard.
- In the Dynatrace menu, go to Mobile.
- Select the mobile application that you want to configure.
- Select More (…) > Edit in the upper-right corner of the tile with your application name.
- From the mobile app settings, go to General > Enablement and cost control.
- Turn on Enable Session Replay on crashes.
- From the mobile app settings, go to General > Data privacy.
- Turn on Enable user opt-in mode.
- From the mobile app settings, go to Instrumentation wizard, and select Android or iOS.
- Follow the steps in the instrumentation wizard.
For Android Gradle plugin versions 4.0 and 4.1, you need to change the compile option to Java 8. This can be done during the instrumentation wizard step called Apply the Dynatrace plugin and add the plugin configuration. Add the following code to the top-level build file:
compileOptions {
sourceCompatibility 1.8
targetCompatibility 1.8
}
compileOptions {
sourceCompatibility("1.8")
targetCompatibility("1.8")
}
For Android Gradle plugin 4.2+, Java 8 is used by default, so no configuration change is needed.
Mask sensitive data
Session Replay on crashes comes with three predefined masking levels:
- Safest—all the editable texts fields, images, labels, web views, and switches are masked.
- Safe—all the editable texts fields are masked.
- Custom—by default, masks the same elements as Safest, but you can decide exactly which app components or views should be masked.
Change masking level
By default, OneAgent applies the Safest masking level. To change it to the Safe or Custom level, use the API to configure OneAgent.
MaskingConfiguration config = new MaskingConfiguration.Safe(); // .Safest or .Custom
DynatraceSessionReplay.setConfiguration(Configuration.builder()
.withMaskingConfiguration(config)
.build());
val config = MaskingConfiguration.Safe() // .Safest or .Custom
DynatraceSessionReplay.setConfiguration(Configuration.builder()
.withMaskingConfiguration(config)
.build())
Configure custom masking
If you set the data masking level to Custom, you can use additional API methods to decide exactly which app components or views should be masked.
Mask views
You can enable or disable masking globally or for the selected components, such as texts fields, images, labels, web views, and switches.
Set<Class<? extends View>> set = new HashSet<Class<? extends View>>()\{{
add(ImageView.class);
add(WebView.class);
}};
new MaskingConfiguration.Custom().addMaskedView(ImageView.class); // Adds one masking view
new MaskingConfiguration.Custom().addMaskedViews(set); // Adds all masking views
new MaskingConfiguration.Custom().removeMaskedView(ImageView.class); // Removes one masking view
new MaskingConfiguration.Custom().removeAllMaskedViews(); // Removes all masking views
MaskingConfiguration.Custom().addMaskedView(ImageView::class.java) // Adds one masking view
MaskingConfiguration.Custom().addMaskedViews(setOf(ImageView::class.java, WebView::class.java)) // Adds all masking views
MaskingConfiguration.Custom().removeMaskedView(ImageView::class.java) // Removes one masking view
MaskingConfiguration.Custom().removeAllMaskedViews() // Removes all masking views
Mask views using android:tag
You can also enable or disable masking of the selected views based on their android:tag
.
Set<Integer> set = new HashSet<Integer>()\{{
add(R.id.view_id1);
add(R.id.view_id2);
}};
new MaskingConfiguration.Custom().addMaskedIds(set);
new MaskingConfiguration.Custom().addNonMaskedIds(set);
new MaskingConfiguration.Custom().removeMaskedIds(set);
new MaskingConfiguration.Custom().removeNonMaskedIds(set);
MaskingConfiguration.Custom().addMaskedIds(setOf(R.id.view_id1, R.id.view_id2))
MaskingConfiguration.Custom().addNonMaskedIds(setOf(R.id.view_id1, R.id.view_id2))
MaskingConfiguration.Custom().removeMaskedIds(setOf(R.id.view_id1, R.id.view_id2))
MaskingConfiguration.Custom().removeNonMaskedIds(setOf(R.id.view_id1, R.id.view_id2))
Mask views using a masking tag
You can also mask a view by adding the data-dtrum-mask
masking tag to the view's android:tag
. A view with this masking tag is always masked.
Enable Session Replay logs
You can enable Session Replay logs the same way as for OneAgent. See Debug logging for OneAgent for more information.
Capture custom events
Session Replay records only certain events. However, you can track an event that is not supported by default.
DynatraceSessionReplay.trackCustomEvent("User logged")
DynatraceSessionReplay.trackCustomEvent("User logged")
Change transmission mode to Wi-Fi for images
By default, all data—information on captured events and images—is sent over any connection. However, you can opt to transfer images only when the users are connected to Wi-Fi to save their mobile data.
DynatraceSessionReplay.setConfiguration(
Configuration.builder()
.withDataTransmissionMode(DataTransmissionMode.NOT_METERED_NETWORK)
.build()
)
DynatraceSessionReplay.setConfiguration(
Configuration.builder()
.withDataTransmissionMode(DataTransmissionMode.NOT_METERED_NETWORK)
.build()
)
Troubleshooting
Ensure that your system meets the Session Replay requirements.
User sessions are not recorded at all
- Ensure that you added the correct properties to your
gradle.properties
file. - Make sure you enabled the user opt-in mode and added a privacy notice.
- Verify that you applied the Dynatrace plugin and added the plugin configuration.
- In the running application console logs, find the following:
- Line stating OneAgent version, for example,
I/dtxAgentCore: #2.Dynatrace OneAgent (Android) 8.xxx.y.zzz Target API ## Android API ##
- Line on Session Replay, for example,
I/dtxSessionReplay: ℹ️ Info -> Session replay agent started.
- Line stating OneAgent version, for example,
User sessions are recorded, but Session Replay is not available
- Verify that Session Replay is enabled. From the mobile app settings, go to General to check that.
- Verify that Session Replay on crashes and user opt-in mode are enabled. From the mobile app settings, go to Instrumentation settings to check that.
- In the running application console logs, check for the following:
- Line confirming that Session Replay is enabled:
D/dtxAgentAdkSettings: #2.switching settings: ServerConfiguration ... "replayConfiguration=ReplayConfiguration"{ "capture=true", // true means Session Replay is enabled; false means Session Replay is disabled ...
- Line on a new session, for example,
I/dtxSessionReplay: ℹ️ Info -> New session started: visitorId=123456789101112, sessionId=0003, sequenceNumber=NNNNN, visitStore=TTTTTT, serverId=DDDDDDD
- Line confirming that Session Replay is enabled: