Migration Guide
Migrating between versions of Sentry's SDK for Android.
Contexts
no longer extendsConcurrentHashMap
, instead we offer a selected set of methods.sentry-android-okhttp
has been removed in favor ofsentry-okhttp
, making the module independent from Android (#3510)- Calling
Sentry.init()
on Android now throws aIllegalArgumentException
, please useSentryAndroid.init()
instead (#3596) - Metrics have been removed from the SDK (#3774)
- Metrics will return but we don't know in what exact form yet
enableTracing
option (a.k.aenable-tracing
) has been removed from the SDK (#3776)- Please set
tracesSampleRate
to a value >= 0.0 for enabling performance instead. The default value isnull
which means performance is disabled.
- Please set
- Change OkHttp sub-spans to span attributes (#3556)
- This will reduce the number of spans created by the SDK
- Replace
synchronized
methods and blocks withReentrantLock
(AutoClosableReentrantLock
) (#3715)- If you are subclassing any Sentry classes, please check if the parent class used
synchronized
before. Please make sure to use the same lock object as the parent class in that case.
- If you are subclassing any Sentry classes, please check if the parent class used
traceOrigins
option (io.sentry.traces.tracing-origins
in manifest) has been removed, please usetracePropagationTargets
(io.sentry.traces.trace-propagation-targets
in manifest`) instead (#3780)profilingEnabled
option (io.sentry.traces.profiling.enable
in manifest) has been removed, please useprofilesSampleRate
(io.sentry.traces.profiling.sample-rate
in manifest) instead (#3780)- Please set
profileSampleRate
to a value >= 0.0 for enabling profiling instead. The default value isnull
which means profiling is disabled.
- Please set
shutdownTimeout
option has been removed, please useshutdownTimeoutMillis
instead (#3780)profilingTracesIntervalMillis
option for Android has been removed (#3780)io.sentry.session-tracking.enable
manifest option has been removed (#3780)Sentry.traceHeaders()
method has been removed, please useSentry.getTraceparent()
instead (#3718)Sentry.reportFullDisplayed()
method has been removed, please useSentry.reportFullyDisplayed()
instead (#3717)User.other
has been removed, please usedata
instead (#3780)SdkVersion.getIntegrations()
has been removed, please usegetIntegrationSet
instead (#3780)SdkVersion.getPackages()
has been removed, please usegetPackageSet()
instead (#3780)Device.language
has been removed, please uselocale
instead (#3780)TraceContext.user
andTraceContextUser
class have been removed, please useuserId
onTraceContext
instead (#3780)TransactionContext.fromSentryTrace()
has been removed, please useSentry.continueTrace()
instead (#3780)SentryDataFetcherExceptionHandler
has been removed, please useSentryGenericDataFetcherExceptionHandler
in combination withSentryInstrumentation
instead (#3780)- One of the
AndroidTransactionProfiler
constructors has been removed, please use a different one (#3780) - Use String instead of UUID for SessionId (#3834)
- The
Session
constructor now takes aString
instead of aUUID
for thesessionId
parameter. Session.getSessionId()
now returns aString
instead of aUUID
.
- The
- The Android minSdk level for all Android modules is now 21 (#3852) (#3851)
- All status codes below 400 are now mapped to
SpanStatus.OK
(#3869) transaction.data
has moved fromextra
tocontexts.trace.data
(#3735)- If you were filtering data in e.g.
beforeSendTransaction
please update accordingly
- If you were filtering data in e.g.
Hub
has been deprecated, we're replacing the following:IHub
has been replaced byIScopes
, however you should be able to simply passIHub
instances to code expectingIScopes
, allowing for an easier migration.HubAdapter.getInstance()
has been replaced byScopesAdapter.getInstance()
- The
.clone()
method onIHub
/IScopes
has been deprecated, please use.pushScope()
or.pushIsolationScope()
instead - Some internal methods like
.getCurrentHub()
and.setCurrentHub()
have also been replaced.
Sentry.popScope
has been replaced by calling.close()
on the token returned bySentry.pushScope()
andSentry.pushIsolationScope()
. The token can also be used in atry-with-resource
block like this:
try (final @NotNull ISentryLifecycleToken ignored = Sentry.pushScope()) {
// this block has its separate current scope
}
as well as:
try (final @NotNull ISentryLifecycleToken ignored = Sentry.pushIsolationScope()) {
// this block has its separate isolation scope
}
You may also use LifecycleHelper.close(token)
, e.g. in case you need to pass the token around for closing later.
- We're introducing some new
Scope
types in the SDK, allowing for better control over what data is attached where. Previously there was a stack of scopes that was pushed and popped. Instead we now fork scopes for a given lifecycle and then restore the previous scopes. SinceHub
is gone, it is also never cloned anymore. Separation of data now happens through the different scope types while making it easier to manipulate exactly what you need without having to attach data at the right time to have it apply where wanted.- Global scope is attached to all events created by the SDK. It can also be modified before
Sentry.init
has been called. It can be manipulated usingSentry.configureScope(ScopeType.GLOBAL, (scope) -> { ... })
. - Isolation scope can be used e.g. to attach data to all events that come up while handling an incoming request. It can also be used for other isolation purposes. It can be manipulated using
Sentry.configureScope(ScopeType.ISOLATION, (scope) -> { ... })
. The SDK automatically forks isolation scope in certain cases like incoming requests, CRON jobs, Spring@Async
and more. - Current scope is forked often and data added to it is only added to events that are created while this scope is active. Data is also passed on to newly forked child scopes but not to parents.
- Global scope is attached to all events created by the SDK. It can also be modified before
Sentry.popScope
has been deprecated, please call.close()
on the token returned bySentry.pushScope
instead or use it in a way described in more detail in "Migration Guide".- We have chosen a default scope that is used for
Sentry.configureScope()
as well as for APIs likeSentry.setTag()
- For Android the type defaults to
CURRENT
scope - For Backend and other JVM applicatons it defaults to
ISOLATION
scope
- For Android the type defaults to
- Event processors on
Scope
can now be ordered by overriding thegetOrder
method on implementations ofEventProcessor
. NOTE: This order only applies to event processors onScope
but notSentryOptions
at the moment. Feel free to request this if you need it. Hub
is deprecated in favor ofScopes
, alongside someHub
relevant APIs. More details can be found in the "Migration Guide" section.- (Android) The JNI layer for sentry-native has now been moved from sentry-java to sentry-native (#3189)
- This now includes prefab support for sentry-native, allowing you to link and access the sentry-native API within your native app code
- Checkout the
sentry-samples/sentry-samples-android
example on how to configure CMake and consumesentry.h
- (Android) Replace thread id with kernel thread id in span data (#3706)
- (Android) Enable Performance V2 by default (#3824)
- With this change cold app start spans will include spans for ContentProviders, Application and Activity load.
- The required Sentry version in version
8.0.0
of the SDK remains unchanged. Sentry's version >= v22.12.0 is required. This only applies to self-hosted Sentry. If you are using sentry.io, no action is needed.
- Bumped Sentry Android SDK to
7.0.0
. Refer to the section below for details about changes to the SDK. - Renamed
experimentalGuardsquareSupport
flag todexguardEnabled
.
You must use Sentry Gradle plugin 4.+ together with the Sentry Android SDK 7.+ otherwise, it might crash at runtime due to binary incompatibility. If you can't do that for some reason, you can specify the Sentry version via the plugin config block:
sentry {
autoInstallation {
sentryVersion.set("7.0.0")
}
}
Similarly, if you have a Sentry SDK (e.g. sentry-android-core
) dependency on one of your Gradle modules and you're updating it to 7.+, make sure the Gradle plugin is at 4.+, or specify the SDK version as shown in the snippet above.
- The minimum supported API level was updated to 19 (
minSdk
). - The
sentry-android-okhttp
classes were deprecated in favor ofsentry-okhttp
, which is a pure Java module and can be used in non-Android projects.- The
SentryOkHttpUtils
class was removed from the public API. If you were using it, consider filing a feature request.
- The
- If you're using
sentry-kotlin-extensions
, it now requireskotlinx-coroutines-core
version1.6.1
or higher. - Moved
enableNdk
andenableScopeSync
fromSentryOptions
toSentryAndroidOptions
. - Changed the return type of
SentryApolloInterceptor.BeforeSpanCallback
fromISpan
toISpan?
. Scope
now implements theIScope
interface, therefore some methods likeScopeCallback.run
acceptIScope
now.- Some
Sentry.startTransaction
overloads do not exist anymore, and instead, you can set old options by passing aTransactionOptions
object in.
For example:
// old
val transaction = Sentry.startTransaction("name", "op", bindToScope = true)
// new
val transaction = Sentry.startTransaction("name", "op", TransactionOptions().apply { isBindToScope = true })
Sentry.getSpan()
now returns the root span/transaction instead of the latest span.- This will make the span hierarchy leaner and more readable.
- The SDK now captures failed HTTP and GraphQL (Apollo) requests by default.
- This can increase your event consumption and may affect your quota, because we will report failed network requests as Sentry events if you're using the
sentry-android-okhttp
orsentry-apollo-3
integrations by default. You can customize what errors you want/don't want to have reported for OkHttp and Apollo3 respectively.
- This can increase your event consumption and may affect your quota, because we will report failed network requests as Sentry events if you're using the
- Added a deadline timeout for automatic transactions.
- This affects all automatically generated transactions on Android (UI, clicks). The default timeout is 30s, meaning the automatic transaction will be force-finished with the status
deadline_exceeded
when it reaches the deadline.
- This affects all automatically generated transactions on Android (UI, clicks). The default timeout is 30s, meaning the automatic transaction will be force-finished with the status
- The SDK now sets
ip_address
to {{auto}} by default, even if sendDefaultPII is disabled.- We recommend you instead use the "Prevent Storing of IP Addresses" option in the "Security & Privacy" project settings on sentry.io.
- The
maxSpans
setting (defaults to 1000) is now enforced for nested child spans. This means a single transaction can havemaxSpans
number of children (nested or not) at most.
Make sure to align all Sentry dependencies (like -timber
, -okhttp
or other packages) to the same version when bumping the SDK to 7.+, otherwise, it will crash at runtime due to binary incompatibility.
For example, if you're using the Sentry Android Gradle plugin with the autoInstallation
feature (enabled by default), make sure to use version 4.+ of the Gradle plugin together with version 7.+ of the SDK. If you can't do that for some reason, you can specify the Sentry version via the plugin config block:
sentry {
autoInstallation {
sentryVersion.set("7.0.0")
}
}
Similarly, if you have a Sentry SDK (e.g. sentry-android-core
) dependency on one of your Gradle modules and you're updating it to 7.+, make sure the Gradle plugin is at 4.+ or specify the SDK version as shown in the snippet above.
- Starting with version
7.0.0
ofsentry
, Sentry's version >= v22.12.0 is required to properly ingest transactions with unfinished spans. This only applies to self-hosted Sentry. If you are using sentry.io, no action is needed.
The sentry-compose-android
and sentry-compose
integrations now declare their upstream dependencies as compileOnly
. Make sure to have the androidx.navigation:navigation-compose
, androidx.compose.runtime:runtime
, and androidx.compose.ui:ui
dependencies on the classpath if you're using those integrations. Otherwise, the application will crash with a NoClassDefFoundError
exception.
The sentry-android-okhttp
, sentry-android-fragment
, and sentry-android-timber
integrations now declare their upstream dependencies as compileOnly
. Make sure to have the okhttp
, fragment
, and timber
dependencies on the classpath if you're using those integrations or the application will crash with a NoClassDefFoundError
exception.
- Kotlin plugin is upgraded to
1.6.10
.
This version is still compatible with Kotlin 1.4
.
This only affects integrations that are written in Kotlin, such as timber
, fragment
, okhttp
, navigation
and compose
.
Kotlin plugin is upgraded to
1.5
.Kotlin
languageVersion
is upgraded to1.4
.Gson
is removed as a transitive dependency and vendored in the SDK.- Protocol classes now implement the
JsonSerializable
andJsonDeserializer
interfaces.
- Protocol classes now implement the
SentryOptions#shutdownTimeout
is renamed toshutdownTimeoutMillis
.Removed
@Deprecated
and@ApiStatus.ScheduledForRemoval
methodsITransaction#setRequest
ITransaction#getRequest
ITransaction#getContexts
SentryBaseEvent#getOriginThrowable
SentryOptions#getCacheDirSize
SentryOptions#setCacheDirSize
SentryOptions#isEnableSessionTracking
SentryOptions#setEnableSessionTracking
Removed unnecessary abstractions
IBuildInfoProvider
is nowBuildInfoProvider
only.IHandler
is nowMainLooperHandler
only.
ISpan
now has higher precision using theSystem#nanoTime
instead of milliseconds.Hints changed its type from
Object
toio.sentry.Hint
Old:
Sentry.captureException(RuntimeException("exception"), "myStringHint")
New:
val hints = mutableMapOf<String, Any>("myHint" to "myStringHint")
Sentry.captureException(RuntimeException("exception"), hints)
SentryOptions#enableScopeSync
is now enabled by default, to disable it, see the code snippet below.
AndroidManifest.xml
<meta-data
android:name="io.sentry.ndk.scope-sync.enable"
android:value="false"
/>
SentryOptions#sendClientReports
is now enabled by default. To disable it, use the code snippet below:
AndroidManifest.xml
<meta-data
android:name="io.sentry.send-client-reports"
android:value="false"
/>
- Starting with version
6.0.0
ofsentry
, Sentry's version >= v21.9.0 is required or you have to manually disable sending client reports via thesendClientReports
option. This only applies to self-hosted Sentry. If you are using sentry.io, no action is needed.
There are more changes and refactors, but they are not user breaking changes.
Starting from version 5.6.2
, the Timber.tag
usage is no longer supported by our SDK (the tag will not be captured and reflected on Sentry). Please, vote on this GitHub issue to let us know if we should provide support for that.
Support for Timber.tag
has been brought back in version 5.7.2
.
The io.sentry.android.gradle
>= 3.0.0
requires Android Gradle Plugin >= 7.0.0. For older versions of the Android Gradle Plugin, use io.sentry.android.gradle:2.+
.
The autoUpload
flag has been deprecated in favor of two new options:
includeProguardMapping
- Disables/enables Proguard mapping functionality. When enabled, generates a UUID and attempts to upload a Proguard mapping associated with that UUID to Sentry. WhenautoUploadProguardMapping
is disabled, the plugin will only generate asentry-debug-meta.properties
file containing UUID, which can later be used to manually upload the mapping using, for example sentry-cli.autoUploadProguardMapping
- Defines whether the gradle plugin should attempt to auto-upload the mapping file to Sentry. WhenincludeProguardMapping
is disabled, this flag has no effect.
Old:
sentry {
autoUpload = false
}
New:
sentry {
includeProguardMapping = true
autoUploadProguardMapping = false
}
The io.sentry.android.gradle
enables the tracing instrumentation (via bytecode manipulation) for androidx.sqlite
and androidx.room
libraries by default, to disable it, see the code snippet below.
sentry {
// Enable or disable the tracing instrumentation.
// Does auto instrumentation for 'androidx.sqlite' and 'androidx.room' libraries.
// It starts and finishes a Span within any CRUD operation.
// Default is enabled.
// Only available v3.0.0 and above.
tracingInstrumentation {
enabled = false
}
}
The io.sentry.android.gradle
>= 2.0.0
requires Android Gradle Plugin >= 4.0.0.
The io.sentry.android.gradle
>= 2.0.0
must be applied to the app/build.gradle
module (or the module that has com.android.application
plugin applied).
The io.sentry.android.gradle
>= 2.0.0
publishes the Gradle Plugin Marker to Maven Central. As a result, you no longer need to set the classpath
.
Old:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'io.sentry:sentry-android-gradle-plugin:{version}'
}
}
apply plugin: 'io.sentry.android.gradle'
New:
plugins {
id "io.sentry.android.gradle" version "{version}"
}
buildscript {
repositories {
mavenCentral()
}
}
The io.sentry.android.gradle
has been rewritten in Kotlin. As a result, the Groovy or Kotlin DSL syntax has slightly changed.
The autoProguardConfig
flag has been removed, the Android SDK >= 2.0.0
version already merges the ProGuard rules automatically.
Old:
sentry {
autoProguardConfig false
autoUpload true
uploadNativeSymbols false
includeNativeSources false
}
New:
sentry {
autoUpload = true
uploadNativeSymbols = false
includeNativeSources = false
}
You may remove android:extractNativeLibs="true"
meta-data in the AndroidManifest
file or android.bundle.enableUncompressedNativeLibs=false
in the gradle.properties
file if you're using the Android Native Development Kit. Sentry can now symbolicate events with the default value of extractNativeLibs and android.bundle.enableUncompressedNativeLibs.
Sentry#startTransaction
by default does not bind created transaction to the scope. To start transaction with binding to the scope, use one of the new overloaded startTransaction
methods taking bindToScope
parameter and set it to true
. Bound transaction can be retrieved with Sentry#getSpan
.
All SDK methods have been annotated with JetBrains Annotations: @Nullable
and @NotNull
. Kotlin compiler respects these annotations, so in Kotlin code, some fields that were recognized as not-null, are now nullable, and the other way around.
SentryBaseEvent#getOriginThrowable
has been deprecated in favor of SentryBaseEvent#getThrowable
, and SentryBaseEvent#getThrowable
now returns the unwrapped throwable.
SentryOptions#getCacheDirSize
has been deprecated in favor of SentryOptions#getMaxCacheItems
.
InvalidDsnException
has been removed. It is replaced by IllegalArgumentException
.
EventProcessor
interface has a new default
method which could break the instantiation when using trailing lambdas.
Old:
SentryOptions#addEventProcessor { event, _ -> event }
New:
SentryOptions#addEventProcessor(object : EventProcessor {
override fun process(event: SentryEvent, hint: Hint): SentryEvent? {
return event
}
})
A random generated installationId
replaces Settings.Secure.ANDROID_ID
, which has been removed. This may affect the number of unique users displayed on the the Issues page and Alerts. If you always set a custom user using Sentry.setUser(customUser)
, the behavior has not changed. While you don't have to make any update, if you want to maintain the old behavior, use the following code snippet:
User user = new User();
user.setId(Settings.Secure.ANDROID_ID);
Sentry.setUser(user);
SentryOptions#setEnableSessionTracking(boolean)
is deprecated in favor of SentryOptions#setEnableAutoSessionTracking(boolean)
. It will be removed in future.
Old:
SentryAndroid.init(this, options -> {
options.setEnableSessionTracking(false);
});
New:
SentryAndroid.init(this, options -> {
options.setEnableAutoSessionTracking(false);
});
io.sentry.session-tracking.enable
AndroidManifest meta-data is deprecated in favor of io.sentry.auto-session-tracking.enable
. It will be removed in future.
Old:
AndroidManifest.xml
<application>
<meta-data
android:name="io.sentry.session-tracking.enable"
android:value="false"
/>
</application>
New:
AndroidManifest.xml
<application>
<meta-data
android:name="io.sentry.auto-session-tracking.enable"
android:value="false"
/>
</application>
operation
is now a required property of the SentryTransaction
and SentrySpan
. Whenever a transaction or span is started, the value for operation
must be provided:
Sentry.startTransaction("transaction-name", "operation-name");
The package io.sentry.core
has been renamed to io.sentry
. To compile correctly, replace the strings on all the usages from io.sentry.core.
to io.sentry.
Other than that, the APIs didn't change. Release Heath sets by default. If you prefer not to track the health of your releases, disable it with:
<application>
<meta-data
android:name="io.sentry.session-tracking.enable"
android:value="false"
/>
</application>
With Sentry Android, we've updated the API to resemble the Unified API more closely. And now that the SDK isn't built on top of io.sentry:sentry-java
, Sentry Android has more Android-specific features.
If you want to upgrade from the previous version of the SDK, please check the following sections of changes that may need updating in your code.
The file sentry.properties
used by the previous version of the SDK has been discontinued. Configurations for the new SDK are in AndroidManifest.xml
or directly in the code.
Example of the configuration in the Manifest:
<application>
<!-- Example of the Sentry DSN setting -->
<meta-data
android:name="io.sentry.dsn"
android:value="https://examplePublicKey@o0.ingest.sentry.io/0"
/>
</application>
If you want to set the configuration manually in the code, you need to initialize the SDK with SentryAndroid.init()
--- described in Installation --- in the same file as SentryAndroidOptions
, which holds configuration items.
The new SDK can initialize automatically, all you need to do is provide the DSN in your Manifest file, as shown in the previous example in Configuration.
If you want to register any callback to filter and modify events and/or breadcrumbs, or if you want to provide the configuration values via code, you need to initialize the SDK using the SentryAndroid.init()
.
To initialize the SDK manually:
Disable the
auto-init
feature by providing the following line in the manifest:Copied<application> <meta-data android:name="io.sentry.auto-init" android:value="false" /> </application>
Initialize the SDK directly in your application:
SentryAndroid.init(this, options -> {
options.setDsn("https://examplePublicKey@o0.ingest.sentry.io/0");
});
Please note that the new SDK will send with each event a release version in a different format than the previous SDK.
If you are using the GitHub or GitLab integrations, you need to do one of the following:
- Use the new format
- Set the release in your
AndroidManifest.xml
- Change your code as described in the configuration section
Old:
Sentry.getContext().addTag("tagName", "tagValue");
New:
Sentry.setTag("tagName", "tagValue");
Old:
try {
int x = 1 / 0;
} catch (Exception e) {
Sentry.capture(e);
}
New:
try {
int x = 1 / 0;
} catch (Exception e) {
Sentry.captureException(e);
}
Old:
Sentry.capture("This is a test");
New:
Sentry.captureMessage("This is a test"); // SentryLevel.INFO by default
Sentry.captureMessage("This is a test", SentryLevel.WARNING); // or specific level
Old:
Sentry.getContext().recordBreadcrumb(
new BreadcrumbBuilder().setMessage("User made an action").build()
);
New:
Sentry.addBreadcrumb("User made an action");
Old:
Sentry.getContext().setUser(
new UserBuilder().setEmail("hello@sentry.io").build()
);
New:
User user = new User();
user.setEmail("hello@sentry.io");
Sentry.setUser(user);
Old:
Sentry.getContext().addExtra("extra", "thing");
New:
Sentry.setExtra("extra", "thing");
Old:
Sentry.clearContext();
New:
Sentry.configureScope(s -> s.clear());
Disable the autoProguardConfig
flag from the Sentry Gradle Plugin since io.sentry:sentry-android
>= 2.0.0
does this automatically.
sentry {
autoProguardConfig false
}
Our documentation is open source and available on GitHub. Your contributions are welcome, whether fixing a typo (drat!) or suggesting an update ("yeah, this would be better").