Skip to content

Commit

Permalink
Merge ea117ff into f1fdb9f
Browse files Browse the repository at this point in the history
  • Loading branch information
adinauer committed May 14, 2024
2 parents f1fdb9f + ea117ff commit dcad3c9
Show file tree
Hide file tree
Showing 354 changed files with 10,818 additions and 4,787 deletions.
55 changes: 55 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,60 @@
# Changelog

## Unreleased

Version 8 of the Sentry Android/Java SDK brings a variety of features and fixes. The most notable changes are:

- New `Scope` types have been introduced, see "Behavioural Changes" for more details.
- Lifecycle tokens have been introduced to manage `Scope` lifecycle, see "Behavioural Changes" for more details.
- `Hub` has been replaced by `Scopes`

### Behavioural Changes

- 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. Since `Hub` 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 using `Sentry.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.
- `Sentry.popScope` has been deprecated, please call `.close()` on the token returned by `Sentry.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 API like `Sentry.setTag()`
- For Android the type defaults to `CURRENT` scope
- For Backend and other JVM applicatons it defaults to `ISOLATION` scope
- Event processors on `Scope` can now be ordered by overriding the `getOrder` method on implementations of `EventProcessor`. NOTE: This order only applies to event processors on `Scope` but not `SentryOptions` at the moment. Feel free to request this if you need it.
- `Hub` is deprecated in favor of `Scopes`, alongside some `Hub` relevant APIs. More details can be found in the "Migration Guide" section.

### Breaking Changes

- `Contexts` no longer extends `ConcurrentHashMap`, instead we offer a selected set of methods.

### Migration Guide / Deprecations

- `Hub` has been deprecated, we're replacing the following:
- `IHub` has been replaced by `IScopes`, however you should be able to simply pass `IHub` instances to code expecting `IScopes`, allowing for an easier migration.
- `HubAdapter.getInstance()` has been replaced by `ScopesAdapter.getInstance()`
- The `.clone()` method on `IHub`/`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 by `Sentry.pushScope()` and `Sentry.pushIsolationScope()`. The token can also be used in a `try` 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.

### Features

- Report exceptions returned by Throwable.getSuppressed() to Sentry as exception groups ([#3396] https://github.com/getsentry/sentry-java/pull/3396)

## 7.9.0

### Features
Expand Down
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ allprojects {
dependsOn("cleanTest")
}
withType<JavaCompile> {
options.compilerArgs.addAll(arrayOf("-Xlint:all", "-Werror", "-Xlint:-classfile", "-Xlint:-processing"))
options.compilerArgs.addAll(arrayOf("-Xlint:all", "-Werror", "-Xlint:-classfile", "-Xlint:-processing", "-Xlint:-try"))
}
}
}
Expand Down
31 changes: 17 additions & 14 deletions sentry-android-core/api/sentry-android-core.api
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ public final class io/sentry/android/core/ActivityBreadcrumbsIntegration : andro
public fun onActivitySaveInstanceState (Landroid/app/Activity;Landroid/os/Bundle;)V
public fun onActivityStarted (Landroid/app/Activity;)V
public fun onActivityStopped (Landroid/app/Activity;)V
public fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V
public fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V
}

public final class io/sentry/android/core/ActivityFramesTracker {
Expand All @@ -33,7 +33,7 @@ public final class io/sentry/android/core/ActivityLifecycleIntegration : android
public fun onActivitySaveInstanceState (Landroid/app/Activity;Landroid/os/Bundle;)V
public fun onActivityStarted (Landroid/app/Activity;)V
public fun onActivityStopped (Landroid/app/Activity;)V
public fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V
public fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V
}

public final class io/sentry/android/core/AndroidCpuCollector : io/sentry/IPerformanceSnapshotCollector {
Expand Down Expand Up @@ -87,7 +87,7 @@ public class io/sentry/android/core/AndroidProfiler$ProfileStartData {
public final class io/sentry/android/core/AnrIntegration : io/sentry/Integration, java/io/Closeable {
public fun <init> (Landroid/content/Context;)V
public fun close ()V
public final fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V
public final fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V
}

public final class io/sentry/android/core/AnrIntegrationFactory {
Expand All @@ -97,14 +97,15 @@ public final class io/sentry/android/core/AnrIntegrationFactory {

public final class io/sentry/android/core/AnrV2EventProcessor : io/sentry/BackfillingEventProcessor {
public fun <init> (Landroid/content/Context;Lio/sentry/android/core/SentryAndroidOptions;Lio/sentry/android/core/BuildInfoProvider;)V
public fun getOrder ()Ljava/lang/Long;
public fun process (Lio/sentry/SentryEvent;Lio/sentry/Hint;)Lio/sentry/SentryEvent;
public fun process (Lio/sentry/protocol/SentryTransaction;Lio/sentry/Hint;)Lio/sentry/protocol/SentryTransaction;
}

public class io/sentry/android/core/AnrV2Integration : io/sentry/Integration, java/io/Closeable {
public fun <init> (Landroid/content/Context;)V
public fun close ()V
public fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V
public fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V
}

public final class io/sentry/android/core/AnrV2Integration$AnrV2Hint : io/sentry/hints/BlockingFlushHint, io/sentry/hints/AbnormalExit, io/sentry/hints/Backfillable {
Expand All @@ -123,13 +124,13 @@ public final class io/sentry/android/core/AppComponentsBreadcrumbsIntegration :
public fun onConfigurationChanged (Landroid/content/res/Configuration;)V
public fun onLowMemory ()V
public fun onTrimMemory (I)V
public fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V
public fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V
}

public final class io/sentry/android/core/AppLifecycleIntegration : io/sentry/Integration, java/io/Closeable {
public fun <init> ()V
public fun close ()V
public fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V
public fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V
}

public final class io/sentry/android/core/AppState {
Expand Down Expand Up @@ -177,7 +178,7 @@ public final class io/sentry/android/core/CurrentActivityIntegration : android/a
public fun onActivitySaveInstanceState (Landroid/app/Activity;Landroid/os/Bundle;)V
public fun onActivityStarted (Landroid/app/Activity;)V
public fun onActivityStopped (Landroid/app/Activity;)V
public fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V
public fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V
}

public final class io/sentry/android/core/DeviceInfoUtil {
Expand All @@ -193,7 +194,7 @@ public abstract class io/sentry/android/core/EnvelopeFileObserverIntegration : i
public fun <init> ()V
public fun close ()V
public static fun getOutboxFileObserver ()Lio/sentry/android/core/EnvelopeFileObserverIntegration;
public final fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V
public final fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V
}

public abstract interface class io/sentry/android/core/IDebugImagesLoader {
Expand All @@ -219,23 +220,24 @@ public final class io/sentry/android/core/NdkIntegration : io/sentry/Integration
public static final field SENTRY_NDK_CLASS_NAME Ljava/lang/String;
public fun <init> (Ljava/lang/Class;)V
public fun close ()V
public final fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V
public final fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V
}

public final class io/sentry/android/core/NetworkBreadcrumbsIntegration : io/sentry/Integration, java/io/Closeable {
public fun <init> (Landroid/content/Context;Lio/sentry/android/core/BuildInfoProvider;Lio/sentry/ILogger;)V
public fun close ()V
public fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V
public fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V
}

public final class io/sentry/android/core/PhoneStateBreadcrumbsIntegration : io/sentry/Integration, java/io/Closeable {
public fun <init> (Landroid/content/Context;)V
public fun close ()V
public fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V
public fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V
}

public final class io/sentry/android/core/ScreenshotEventProcessor : io/sentry/EventProcessor {
public fun <init> (Lio/sentry/android/core/SentryAndroidOptions;Lio/sentry/android/core/BuildInfoProvider;)V
public fun getOrder ()Ljava/lang/Long;
public fun process (Lio/sentry/SentryEvent;Lio/sentry/Hint;)Lio/sentry/SentryEvent;
public fun process (Lio/sentry/protocol/SentryTransaction;Lio/sentry/Hint;)Lio/sentry/protocol/SentryTransaction;
}
Expand Down Expand Up @@ -360,15 +362,15 @@ public final class io/sentry/android/core/SystemEventsBreadcrumbsIntegration : i
public fun <init> (Landroid/content/Context;)V
public fun <init> (Landroid/content/Context;Ljava/util/List;)V
public fun close ()V
public fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V
public fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V
}

public final class io/sentry/android/core/TempSensorBreadcrumbsIntegration : android/hardware/SensorEventListener, io/sentry/Integration, java/io/Closeable {
public fun <init> (Landroid/content/Context;)V
public fun close ()V
public fun onAccuracyChanged (Landroid/hardware/Sensor;I)V
public fun onSensorChanged (Landroid/hardware/SensorEvent;)V
public fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V
public fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V
}

public final class io/sentry/android/core/UserInteractionIntegration : android/app/Application$ActivityLifecycleCallbacks, io/sentry/Integration, java/io/Closeable {
Expand All @@ -381,11 +383,12 @@ public final class io/sentry/android/core/UserInteractionIntegration : android/a
public fun onActivitySaveInstanceState (Landroid/app/Activity;Landroid/os/Bundle;)V
public fun onActivityStarted (Landroid/app/Activity;)V
public fun onActivityStopped (Landroid/app/Activity;)V
public fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V
public fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V
}

public final class io/sentry/android/core/ViewHierarchyEventProcessor : io/sentry/EventProcessor {
public fun <init> (Lio/sentry/android/core/SentryAndroidOptions;)V
public fun getOrder ()Ljava/lang/Long;
public fun process (Lio/sentry/SentryEvent;Lio/sentry/Hint;)Lio/sentry/SentryEvent;
public fun process (Lio/sentry/protocol/SentryTransaction;Lio/sentry/Hint;)Lio/sentry/protocol/SentryTransaction;
public static fun snapshotViewHierarchy (Landroid/app/Activity;Lio/sentry/ILogger;)Lio/sentry/protocol/ViewHierarchy;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import android.os.Bundle;
import io.sentry.Breadcrumb;
import io.sentry.Hint;
import io.sentry.IHub;
import io.sentry.IScopes;
import io.sentry.Integration;
import io.sentry.SentryLevel;
import io.sentry.SentryOptions;
Expand All @@ -23,21 +23,21 @@ public final class ActivityBreadcrumbsIntegration
implements Integration, Closeable, Application.ActivityLifecycleCallbacks {

private final @NotNull Application application;
private @Nullable IHub hub;
private @Nullable IScopes scopes;
private boolean enabled;

public ActivityBreadcrumbsIntegration(final @NotNull Application application) {
this.application = Objects.requireNonNull(application, "Application is required");
}

@Override
public void register(final @NotNull IHub hub, final @NotNull SentryOptions options) {
public void register(final @NotNull IScopes scopes, final @NotNull SentryOptions options) {
final SentryAndroidOptions androidOptions =
Objects.requireNonNull(
(options instanceof SentryAndroidOptions) ? (SentryAndroidOptions) options : null,
"SentryAndroidOptions is required");

this.hub = Objects.requireNonNull(hub, "Hub is required");
this.scopes = Objects.requireNonNull(scopes, "Scopes are required");
this.enabled = androidOptions.isEnableActivityLifecycleBreadcrumbs();
options
.getLogger()
Expand All @@ -54,8 +54,9 @@ public void register(final @NotNull IHub hub, final @NotNull SentryOptions optio
public void close() throws IOException {
if (enabled) {
application.unregisterActivityLifecycleCallbacks(this);
if (hub != null) {
hub.getOptions()
if (scopes != null) {
scopes
.getOptions()
.getLogger()
.log(SentryLevel.DEBUG, "ActivityBreadcrumbsIntegration removed.");
}
Expand Down Expand Up @@ -100,7 +101,7 @@ public synchronized void onActivityDestroyed(final @NotNull Activity activity) {
}

private void addBreadcrumb(final @NotNull Activity activity, final @NotNull String state) {
if (hub == null) {
if (scopes == null) {
return;
}

Expand All @@ -114,7 +115,7 @@ private void addBreadcrumb(final @NotNull Activity activity, final @NotNull Stri
final Hint hint = new Hint();
hint.set(ANDROID_ACTIVITY, activity);

hub.addBreadcrumb(breadcrumb, hint);
scopes.addBreadcrumb(breadcrumb, hint);
}

private @NotNull String getActivityName(final @NotNull Activity activity) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
import android.view.View;
import androidx.annotation.NonNull;
import io.sentry.FullyDisplayedReporter;
import io.sentry.IHub;
import io.sentry.IScope;
import io.sentry.IScopes;
import io.sentry.ISpan;
import io.sentry.ITransaction;
import io.sentry.Instrumenter;
Expand Down Expand Up @@ -60,7 +60,7 @@ public final class ActivityLifecycleIntegration

private final @NotNull Application application;
private final @NotNull BuildInfoProvider buildInfoProvider;
private @Nullable IHub hub;
private @Nullable IScopes scopes;
private @Nullable SentryAndroidOptions options;

private boolean performanceEnabled = false;
Expand Down Expand Up @@ -102,13 +102,13 @@ public ActivityLifecycleIntegration(
}

@Override
public void register(final @NotNull IHub hub, final @NotNull SentryOptions options) {
public void register(final @NotNull IScopes scopes, final @NotNull SentryOptions options) {
this.options =
Objects.requireNonNull(
(options instanceof SentryAndroidOptions) ? (SentryAndroidOptions) options : null,
"SentryAndroidOptions is required");

this.hub = Objects.requireNonNull(hub, "Hub is required");
this.scopes = Objects.requireNonNull(scopes, "Scopes are required");

performanceEnabled = isPerformanceEnabled(this.options);
fullyDisplayedReporter = this.options.getFullyDisplayedReporter();
Expand Down Expand Up @@ -150,10 +150,10 @@ private void stopPreviousTransactions() {

private void startTracing(final @NotNull Activity activity) {
WeakReference<Activity> weakActivity = new WeakReference<>(activity);
if (hub != null && !isRunningTransactionOrTrace(activity)) {
if (scopes != null && !isRunningTransactionOrTrace(activity)) {
if (!performanceEnabled) {
activitiesWithOngoingTransactions.put(activity, NoOpTransaction.getInstance());
TracingUtils.startNewTrace(hub);
TracingUtils.startNewTrace(scopes);
} else {
// as we allow a single transaction running on the bound Scope, we finish the previous ones
stopPreviousTransactions();
Expand Down Expand Up @@ -225,7 +225,7 @@ private void startTracing(final @NotNull Activity activity) {

// we can only bind to the scope if there's no running transaction
ITransaction transaction =
hub.startTransaction(
scopes.startTransaction(
new TransactionContext(
activityName,
TransactionNameSource.COMPONENT,
Expand Down Expand Up @@ -278,7 +278,7 @@ private void startTracing(final @NotNull Activity activity) {
}

// lets bind to the scope so other integrations can pick it up
hub.configureScope(
scopes.configureScope(
scope -> {
applyScope(scope, transaction);
});
Expand Down Expand Up @@ -356,10 +356,10 @@ private void finishTransaction(
status = SpanStatus.OK;
}
transaction.finish(status);
if (hub != null) {
if (scopes != null) {
// make sure to remove the transaction from scope, as it may contain running children,
// therefore `finish` method will not remove it from scope
hub.configureScope(
scopes.configureScope(
scope -> {
clearScope(scope, transaction);
});
Expand All @@ -371,9 +371,9 @@ private void finishTransaction(
public synchronized void onActivityCreated(
final @NotNull Activity activity, final @Nullable Bundle savedInstanceState) {
setColdStart(savedInstanceState);
if (hub != null) {
if (scopes != null) {
final @Nullable String activityClassName = ClassUtil.getClassName(activity);
hub.configureScope(scope -> scope.setScreen(activityClassName));
scopes.configureScope(scope -> scope.setScreen(activityClassName));
}
startTracing(activity);
final @Nullable ISpan ttfdSpan = ttfdSpanMap.get(activity);
Expand Down Expand Up @@ -429,10 +429,10 @@ public void onActivityPrePaused(@NonNull Activity activity) {
// well
// this ensures any newly launched activity will not use the app start timestamp as txn start
firstActivityCreated = true;
if (hub == null) {
if (scopes == null) {
lastPausedTime = AndroidDateUtils.getCurrentSentryDateTime();
} else {
lastPausedTime = hub.getOptions().getDateProvider().now();
lastPausedTime = scopes.getOptions().getDateProvider().now();
}
}
}
Expand All @@ -445,10 +445,10 @@ public synchronized void onActivityPaused(final @NotNull Activity activity) {
// well
// this ensures any newly launched activity will not use the app start timestamp as txn start
firstActivityCreated = true;
if (hub == null) {
if (scopes == null) {
lastPausedTime = AndroidDateUtils.getCurrentSentryDateTime();
} else {
lastPausedTime = hub.getOptions().getDateProvider().now();
lastPausedTime = scopes.getOptions().getDateProvider().now();
}
}
}
Expand Down

0 comments on commit dcad3c9

Please sign in to comment.