You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit d501a7e
Browse filesBrowse the repository at this point in the historyBrowse files
authored
feat(anr): Profile main thread when ANR and report ANR profiles to Sentry (#4899)
* Profile main thread when ANR and report ANR profiles to sentry
* docs(changelog): Add ANR profiling integration entry
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Fix api dump file
* Address PR feedback
* refactor(anr): Implement lazy file rotation for ANR profiling
* Update Changelog
* Address PR feedback
* Improve folding logic, cleanup tests
* Add more tests and address feedback
* Update CHANGELOG.md
* Address PR feedcback
* Move logic to event processor
* Update changelog
* Ensure integration is tracked
* Address PR feedback
* Fix tests
* Match manifest property to convention, enable profiling in sample app
* Add more bound checks and null guards
* Remove outdated meta-data
* Properly handle foreground transitions
* Address PR comments
* Address PR feedback
* Address PR feedback
* Address PR feedback
* Re-use thread
* Update Changelop
* Address review
* Address PR feedback
* Replace ANR profiling boolean flag with sample-rate (#5156)
* feat(android): Add enableAnrFingerprinting option (#5168)
* feat(android): Add enableAnrFingerprinting option
Decouple ANR fingerprinting from ANR profiling into a standalone
opt-in option. This allows static fingerprinting of system-frame-only
ANRs regardless of whether profiling is enabled.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(android): Mark enableAnrFingerprinting as experimental
Also enable the option in the sample app.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(android): Default enableAnrFingerprinting to true
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor(android): Remove experimental flag from enableAnrFingerprinting
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix api dump
* Address PR feedback
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Fix tests
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Roman Zavarnitsyn <rom4ek93@gmail.com>
- The `ManifestMetaDataReader` now read the `DIST` ([#5107](https://github.com/getsentry/sentry-java/pull/5107))
48
+
- Add new experimental option to capture profiles for ANRs ([#4899](https://github.com/getsentry/sentry-java/pull/4899))
49
+
- This feature will capture a stack profile of the main thread when it gets unresponsive
50
+
- The profile gets attached to the ANR event on the next app start, providing a flamegraph of the ANR issue on the sentry issue details page
51
+
- Enable via `options.setAnrProfilingSampleRate(<sample-rate>)` or AndroidManifest.xml: `<meta-data android:name="io.sentry.anr.profiling.sample-rate" android:value="[0.0-1.0]" />`
52
+
- The sample rate controls the probability of collecting a profile for each detected foreground ANR (0.0 to 1.0, null to disable)
53
+
- Add `enableAnrFingerprinting` option to reduce ANR noise by assigning static fingerprints to ANR events with system-only stacktraces
54
+
- When enabled, ANRs whose stacktraces contain only system frames (e.g. `java.lang` or `android.os`) are grouped into a single issue instead of creating many separate issues
55
+
- Enable via `options.setEnableAnrFingerprinting(true)` or AndroidManifest.xml: `<meta-data android:name="io.sentry.anr.enable-fingerprinting" android:value="true" />`
48
56
49
57
### Fixes
50
58
@@ -180,7 +188,7 @@
180
188
- Discard envelopes on `4xx` and `5xx` response ([#4950](https://github.com/getsentry/sentry-java/pull/4950))
181
189
- This aims to not overwhelm Sentry after an outage or load shedding (including HTTP 429) where too many events are sent at once
182
190
183
-
### Feature
191
+
### Features
184
192
185
193
- Add a Tombstone integration that detects native crashes without relying on the NDK integration, but instead using `ApplicationExitInfo.REASON_CRASH_NATIVE` on Android 12+. ([#4933](https://github.com/getsentry/sentry-java/pull/4933))
186
194
- Currently exposed via options as an _internal_ API only.
Copy file name to clipboardExpand all lines: sentry-android-core/api/sentry-android-core.api
+78Lines changed: 78 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -347,6 +347,7 @@ public final class io/sentry/android/core/SentryAndroidDateProvider : io/sentry/
347
347
public final class io/sentry/android/core/SentryAndroidOptions : io/sentry/SentryOptions {
348
348
public fun <init> ()V
349
349
public fun enableAllAutoBreadcrumbs (Z)V
350
+
public fun getAnrProfilingSampleRate ()Ljava/lang/Double;
350
351
public fun getAnrTimeoutIntervalMillis ()J
351
352
public fun getBeforeScreenshotCaptureCallback ()Lio/sentry/android/core/SentryAndroidOptions$BeforeCaptureCallback;
352
353
public fun getBeforeViewHierarchyCaptureCallback ()Lio/sentry/android/core/SentryAndroidOptions$BeforeCaptureCallback;
@@ -357,6 +358,7 @@ public final class io/sentry/android/core/SentryAndroidOptions : io/sentry/Sentr
357
358
public fun getScreenshot ()Lio/sentry/android/core/SentryScreenshotOptions;
358
359
public fun getStartupCrashDurationThresholdMillis ()J
359
360
public fun isAnrEnabled ()Z
361
+
public fun isAnrProfilingEnabled ()Z
360
362
public fun isAnrReportInDebug ()Z
361
363
public fun isAttachAnrThreadDump ()Z
362
364
public fun isAttachScreenshot ()Z
@@ -365,6 +367,7 @@ public final class io/sentry/android/core/SentryAndroidOptions : io/sentry/Sentr
365
367
public fun isCollectExternalStorageContext ()Z
366
368
public fun isEnableActivityLifecycleBreadcrumbs ()Z
367
369
public fun isEnableActivityLifecycleTracingAutoFinish ()Z
370
+
public fun isEnableAnrFingerprinting ()Z
368
371
public fun isEnableAppComponentBreadcrumbs ()Z
369
372
public fun isEnableAppLifecycleBreadcrumbs ()Z
370
373
public fun isEnableAutoActivityLifecycleTracing ()Z
@@ -381,6 +384,7 @@ public final class io/sentry/android/core/SentryAndroidOptions : io/sentry/Sentr
381
384
public fun isReportHistoricalTombstones ()Z
382
385
public fun isTombstoneEnabled ()Z
383
386
public fun setAnrEnabled (Z)V
387
+
public fun setAnrProfilingSampleRate (Ljava/lang/Double;)V
384
388
public fun setAnrReportInDebug (Z)V
385
389
public fun setAnrTimeoutIntervalMillis (J)V
386
390
public fun setAttachAnrThreadDump (Z)V
@@ -393,6 +397,7 @@ public final class io/sentry/android/core/SentryAndroidOptions : io/sentry/Sentr
393
397
public fun setDebugImagesLoader (Lio/sentry/android/core/IDebugImagesLoader;)V
394
398
public fun setEnableActivityLifecycleBreadcrumbs (Z)V
395
399
public fun setEnableActivityLifecycleTracingAutoFinish (Z)V
400
+
public fun setEnableAnrFingerprinting (Z)V
396
401
public fun setEnableAppComponentBreadcrumbs (Z)V
397
402
public fun setEnableAppLifecycleBreadcrumbs (Z)V
398
403
public fun setEnableAutoActivityLifecycleTracing (Z)V
@@ -553,6 +558,79 @@ public final class io/sentry/android/core/ViewHierarchyEventProcessor : io/sentr
553
558
public static fun snapshotViewHierarchyAsData (Landroid/app/Activity;Lio/sentry/util/thread/IThreadChecker;Lio/sentry/ISerializer;Lio/sentry/ILogger;)[B
554
559
}
555
560
561
+
public class io/sentry/android/core/anr/AggregatedStackTrace {
562
+
public fun <init> ([Ljava/lang/StackTraceElement;IIJF)V
563
+
public fun addOccurrence (J)V
564
+
public fun getStack ()[Ljava/lang/StackTraceElement;
565
+
}
566
+
567
+
public class io/sentry/android/core/anr/AnrCulpritIdentifier {
568
+
public fun <init> ()V
569
+
public static fun identify (Ljava/util/List;)Lio/sentry/android/core/anr/AggregatedStackTrace;
570
+
public static fun isSystemFrame (Ljava/lang/String;)Z
571
+
}
572
+
573
+
public class io/sentry/android/core/anr/AnrProfile {
574
+
public final field endTimeMs J
575
+
public final field stacks Ljava/util/List;
576
+
public final field startTimeMs J
577
+
public fun <init> (Ljava/util/List;)V
578
+
}
579
+
580
+
public class io/sentry/android/core/anr/AnrProfileManager : java/lang/AutoCloseable {
581
+
public fun <init> (Lio/sentry/SentryOptions;)V
582
+
public fun <init> (Lio/sentry/SentryOptions;Ljava/io/File;)V
583
+
public fun add (Lio/sentry/android/core/anr/AnrStackTrace;)V
584
+
public fun clear ()V
585
+
public fun close ()V
586
+
public fun load ()Lio/sentry/android/core/anr/AnrProfile;
587
+
}
588
+
589
+
public class io/sentry/android/core/anr/AnrProfileRotationHelper {
590
+
public fun <init> ()V
591
+
public static fun deleteLastFile (Ljava/io/File;)Z
592
+
public static fun getFileForRecording (Ljava/io/File;)Ljava/io/File;
593
+
public static fun getLastFile (Ljava/io/File;)Ljava/io/File;
594
+
public static fun rotate ()V
595
+
}
596
+
597
+
public class io/sentry/android/core/anr/AnrProfilingIntegration : io/sentry/Integration, io/sentry/android/core/AppState$AppStateListener, java/io/Closeable, java/lang/Runnable {
598
+
public static final field POLLING_INTERVAL_MS J
599
+
public static final field THRESHOLD_ANR_MS J
600
+
public fun <init> ()V
601
+
protected fun checkMainThread (Ljava/lang/Thread;)V
602
+
public fun close ()V
603
+
protected fun getProfileManager ()Lio/sentry/android/core/anr/AnrProfileManager;
604
+
protected fun getState ()Lio/sentry/android/core/anr/AnrProfilingIntegration$MainThreadState;
605
+
public fun onBackground ()V
606
+
public fun onForeground ()V
607
+
public fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V
608
+
public fun run ()V
609
+
}
610
+
611
+
protected final class io/sentry/android/core/anr/AnrProfilingIntegration$MainThreadState : java/lang/Enum {
612
+
public static final field ANR_DETECTED Lio/sentry/android/core/anr/AnrProfilingIntegration$MainThreadState;
613
+
public static final field IDLE Lio/sentry/android/core/anr/AnrProfilingIntegration$MainThreadState;
614
+
public static final field SUSPICIOUS Lio/sentry/android/core/anr/AnrProfilingIntegration$MainThreadState;
615
+
public static fun valueOf (Ljava/lang/String;)Lio/sentry/android/core/anr/AnrProfilingIntegration$MainThreadState;
616
+
public static fun values ()[Lio/sentry/android/core/anr/AnrProfilingIntegration$MainThreadState;
617
+
}
618
+
619
+
public final class io/sentry/android/core/anr/AnrStackTrace : java/lang/Comparable {
620
+
public final field stack [Ljava/lang/StackTraceElement;
621
+
public final field timestampMs J
622
+
public fun <init> (J[Ljava/lang/StackTraceElement;)V
623
+
public fun compareTo (Lio/sentry/android/core/anr/AnrStackTrace;)I
624
+
public synthetic fun compareTo (Ljava/lang/Object;)I
625
+
public static fun deserialize (Ljava/io/DataInputStream;)Lio/sentry/android/core/anr/AnrStackTrace;
626
+
public fun serialize (Ljava/io/DataOutputStream;)V
627
+
}
628
+
629
+
public final class io/sentry/android/core/anr/StackTraceConverter {
630
+
public fun <init> ()V
631
+
public static fun convert (Lio/sentry/android/core/anr/AnrProfile;)Lio/sentry/protocol/profiling/SentryProfile;
632
+
}
633
+
556
634
public final class io/sentry/android/core/cache/AndroidEnvelopeCache : io/sentry/cache/EnvelopeCache {
557
635
public static final field LAST_ANR_MARKER_LABEL Ljava/lang/String;
558
636
public static final field LAST_ANR_REPORT Ljava/lang/String;
0 commit comments