Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New ANRv2 implementation based on ApplicationExitInfo #2697

Merged
merged 32 commits into from
May 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
f346b26
Initial implementation of ANRv2 (#2549)
romtsn Mar 14, 2023
06f0d7e
Mark previous session as abnormal if an ANR has happened
romtsn Mar 23, 2023
d7cd602
Merge branch 'main' into feat/anr-v2
romtsn Mar 23, 2023
aa0b3fa
Merge branch 'feat/anr-v2' into feat/anr-v2-session-abnormal
romtsn Mar 23, 2023
ab73382
Fix tests
romtsn Mar 23, 2023
63a8f7e
Format code
getsentry-bot Mar 23, 2023
a8efc61
2nd attempt
romtsn Mar 29, 2023
bce19ae
3rd attempt
romtsn Mar 30, 2023
6a73462
Merge branch 'feat/anr-v2-session-abnormal' of github.com:getsentry/s…
romtsn Mar 30, 2023
de79fbe
Formatting
romtsn Mar 30, 2023
5d09a5a
It works
romtsn Mar 31, 2023
67d444d
Formatting
romtsn Mar 31, 2023
a8104a6
Tests
romtsn Mar 31, 2023
7da3a73
Spotless
romtsn Mar 31, 2023
bc9dbe1
api dump
romtsn Mar 31, 2023
6c09cd0
Fix integration tests
romtsn Apr 3, 2023
5857dd0
Format code
getsentry-bot Apr 3, 2023
f1f4bb2
Api dump
romtsn Apr 3, 2023
f97c4f6
Merge branch 'main' into feat/anr-v2
romtsn Apr 4, 2023
0e17b6c
Handle new device properties
romtsn Apr 4, 2023
9a8d419
Merge branch 'feat/anr-v2' into feat/anr-v2-session-abnormal
romtsn Apr 4, 2023
9b823d3
Address PR review
romtsn Apr 4, 2023
642462a
Api dump
romtsn Apr 4, 2023
6f8b473
Merge pull request #2621 from getsentry/feat/anr-v2-session-abnormal
romtsn Apr 4, 2023
d52be74
Parse ANRv2 thread dump into threads interface (#2661)
romtsn Apr 27, 2023
92db968
Merge branch 'main' into feat/anr-v2
markushi Apr 27, 2023
65e6fcf
Merge branch 'main' into feat/anr-v2
romtsn May 3, 2023
dfdeb79
Small tweaks
romtsn May 3, 2023
d2dd643
Spotless
romtsn May 3, 2023
ff24f81
Changelog
romtsn May 4, 2023
893ecf8
Pr id
romtsn May 4, 2023
d5f6ffb
Merge branch 'main' into feat/anr-v2
romtsn May 5, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,18 @@

## Unreleased

## Features
### Features

- Add Screenshot and ViewHierarchy to integrations list ([#2698](https://github.com/getsentry/sentry-java/pull/2698))
- New ANR detection based on [ApplicationExitInfo API](https://developer.android.com/reference/android/app/ApplicationExitInfo) ([#2697](https://github.com/getsentry/sentry-java/pull/2697))
- This implementation completely replaces the old one (based on a watchdog) on devices running Android 11 and above:
- New implementation provides more precise ANR events/ANR rate detection as well as system thread dump information. The new implementation reports ANRs exactly as Google Play Console, without producing false positives or missing important background ANR events.
- However, despite producing many false positives, the old implementation is capable of better enriching ANR errors (which is not available with the new implementation), for example:
- Capturing screenshots at the time of ANR event;
- Capturing transactions and profiling data corresponding to the ANR event;
- Auxiliary information (such as current memory load) at the time of ANR event.
- If you would like us to provide support for the old approach working alongside the new one on Android 11 and above (e.g. for raising events for slow code on main thread), consider upvoting [this issue](https://github.com/getsentry/sentry-java/issues/2693).
- The old watchdog implementation will continue working for older API versions (Android < 11)

### Fixes

Expand Down
2 changes: 2 additions & 0 deletions sentry-android-core/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
INSTALLATION
last_crash
.options-cache/
.scope-cache/
/sentry
25 changes: 25 additions & 0 deletions sentry-android-core/api/sentry-android-core.api
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,29 @@ public final class io/sentry/android/core/AnrIntegration : io/sentry/Integration
public final fun register (Lio/sentry/IHub;Lio/sentry/SentryOptions;)V
}

public final class io/sentry/android/core/AnrIntegrationFactory {
public fun <init> ()V
public static fun create (Landroid/content/Context;Lio/sentry/android/core/BuildInfoProvider;)Lio/sentry/Integration;
}

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 process (Lio/sentry/SentryEvent;Lio/sentry/Hint;)Lio/sentry/SentryEvent;
}

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 final class io/sentry/android/core/AnrV2Integration$AnrV2Hint : io/sentry/hints/BlockingFlushHint, io/sentry/hints/AbnormalExit, io/sentry/hints/Backfillable {
public fun <init> (JLio/sentry/ILogger;JZZ)V
public fun mechanism ()Ljava/lang/String;
public fun shouldEnrich ()Z
public fun timestamp ()Ljava/lang/Long;
}

public final class io/sentry/android/core/AppComponentsBreadcrumbsIntegration : android/content/ComponentCallbacks2, io/sentry/Integration, java/io/Closeable {
public fun <init> (Landroid/content/Context;)V
public fun close ()V
Expand Down Expand Up @@ -297,9 +320,11 @@ public final class io/sentry/android/core/ViewHierarchyEventProcessor : io/sentr
}

public final class io/sentry/android/core/cache/AndroidEnvelopeCache : io/sentry/cache/EnvelopeCache {
public static final field LAST_ANR_REPORT Ljava/lang/String;
public fun <init> (Lio/sentry/android/core/SentryAndroidOptions;)V
public fun getDirectory ()Ljava/io/File;
public static fun hasStartupCrashMarker (Lio/sentry/SentryOptions;)Z
public static fun lastReportedAnr (Lio/sentry/SentryOptions;)Ljava/lang/Long;
public fun store (Lio/sentry/SentryEnvelope;Lio/sentry/Hint;)V
}

Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
import io.sentry.android.core.internal.util.SentryFrameMetricsCollector;
import io.sentry.android.fragment.FragmentLifecycleIntegration;
import io.sentry.android.timber.SentryTimberIntegration;
import io.sentry.cache.PersistingOptionsObserver;
import io.sentry.cache.PersistingScopeObserver;
import io.sentry.compose.gestures.ComposeGestureTargetLocator;
import io.sentry.internal.gestures.GestureTargetLocator;
import io.sentry.transport.NoOpEnvelopeCache;
Expand Down Expand Up @@ -139,6 +141,7 @@ static void initializeIntegrationsAndProcessors(
options.addEventProcessor(new PerformanceAndroidEventProcessor(options, activityFramesTracker));
options.addEventProcessor(new ScreenshotEventProcessor(options, buildInfoProvider));
options.addEventProcessor(new ViewHierarchyEventProcessor(options));
options.addEventProcessor(new AnrV2EventProcessor(context, options, buildInfoProvider));
options.setTransportGate(new AndroidTransportGate(context, options.getLogger()));
final SentryFrameMetricsCollector frameMetricsCollector =
new SentryFrameMetricsCollector(context, options, buildInfoProvider);
Expand Down Expand Up @@ -170,6 +173,11 @@ static void initializeIntegrationsAndProcessors(
options.addCollector(new AndroidCpuCollector(options.getLogger(), buildInfoProvider));
}
options.setTransactionPerformanceCollector(new DefaultTransactionPerformanceCollector(options));

if (options.getCacheDirPath() != null) {
options.addScopeObserver(new PersistingScopeObserver(options));
options.addOptionsObserver(new PersistingOptionsObserver(options));
}
}

private static void installDefaultIntegrations(
Expand Down Expand Up @@ -213,7 +221,7 @@ private static void installDefaultIntegrations(
// AppLifecycleIntegration has to be installed before AnrIntegration, because AnrIntegration
// relies on AppState set by it
options.addIntegration(new AppLifecycleIntegration());
options.addIntegration(new AnrIntegration(context));
options.addIntegration(AnrIntegrationFactory.create(context, buildInfoProvider));

// registerActivityLifecycleCallbacks is only available if Context is an AppContext
if (context instanceof Application) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import io.sentry.SentryOptions;
import io.sentry.exception.ExceptionMechanismException;
import io.sentry.hints.AbnormalExit;
import io.sentry.hints.TransactionEnd;
import io.sentry.protocol.Mechanism;
import io.sentry.util.HintUtils;
import io.sentry.util.Objects;
Expand Down Expand Up @@ -141,7 +142,7 @@ public void close() throws IOException {
* href="https://develop.sentry.dev/sdk/sessions/#crashed-abnormal-vs-errored">Develop Docs</a>
* because we don't know whether the app has recovered after it or not.
*/
static final class AnrHint implements AbnormalExit {
static final class AnrHint implements AbnormalExit, TransactionEnd {

private final boolean isBackgroundAnr;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package io.sentry.android.core;

import android.content.Context;
import android.os.Build;
import io.sentry.Integration;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;

@ApiStatus.Internal
public final class AnrIntegrationFactory {

@NotNull
public static Integration create(
final @NotNull Context context, final @NotNull BuildInfoProvider buildInfoProvider) {
if (buildInfoProvider.getSdkInfoVersion() >= Build.VERSION_CODES.R) {
return new AnrV2Integration(context);
} else {
return new AnrIntegration(context);
}
}
}
Loading
Loading