Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
ba0c7db
feat: minimal tombstone integration (disabled by default, options int…
supervacuus Nov 25, 2025
9933e47
redo a seemingly missed spotlessApply
supervacuus Nov 26, 2025
10b1e94
use non-plural option + mark integration also as internal + update API
supervacuus Nov 26, 2025
f12b658
Merge branch 'main' into feat/tombstone_integration
supervacuus Nov 26, 2025
4b6e1fb
init size exceptions since we know we only need one
supervacuus Nov 27, 2025
95bd726
move `instructionAddressAdjustment` to `SentryStackTrace`
supervacuus Dec 2, 2025
4f03857
add copyright notice to tombstone.proto
supervacuus Dec 2, 2025
936a2f0
add historical tombstone option
supervacuus Dec 2, 2025
28652e0
looks like we need to add a TombstoneEventProcessor anyway.
supervacuus Dec 2, 2025
920221a
...so let's add it to the options if the SDK supports it (adapt to >=…
supervacuus Dec 2, 2025
48ed5e1
Adapt `AndroidEnvelopeCache` to also write Tombstone timestamp markers
supervacuus Dec 2, 2025
10c7a1f
Integrate handling of historical Tombstone option + last tombstone ma…
supervacuus Dec 2, 2025
6cbfdf8
sprinkle with TODOs to highlight next PR steps
supervacuus Dec 2, 2025
4b1919e
fix typo
supervacuus Dec 2, 2025
d931ddc
implement TombstoneParser as Closable and close the tombstone stream
supervacuus Dec 2, 2025
65bc76b
tighten code with final and null annotations.
supervacuus Dec 2, 2025
25f4089
eliminate obsolete null check
supervacuus Dec 2, 2025
7db5895
Deduplicate ApplicationExitInfo handling for corresponding Integratio…
supervacuus Dec 3, 2025
a8ea230
update tombstone message construction
supervacuus Dec 3, 2025
92cb264
Merge branch 'main' into feat/tombstone_integration
supervacuus Dec 3, 2025
ed81771
fix abortMessage check
supervacuus Dec 3, 2025
480bfd6
Merge branch 'main' into feat/tombstone_integration
supervacuus Dec 3, 2025
c8acdf9
Merge branch 'main' into feat/tombstone_integration
supervacuus Dec 3, 2025
125b0c4
convert AnrV2EventProcessor to a more generic ApplicationExitInfoEven…
supervacuus Dec 3, 2025
7e29fbf
reintroduce, update and correct old inline docs where they make sense.
supervacuus Dec 3, 2025
605a840
remove obsolete TombstoneEventProcessor
supervacuus Dec 5, 2025
76ef13c
Merge branch 'main' into feat/tombstone_integration
supervacuus Dec 5, 2025
7f6dbc9
clean up tombstone error handling
supervacuus Dec 5, 2025
58a342f
convert ApplicationExitInfoHistoryDispatcher.removeLatest() to use an…
supervacuus Dec 5, 2025
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
4 changes: 4 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ spotless = "7.0.4"
gummyBears = "0.12.0"
camerax = "1.3.0"
openfeature = "1.18.2"
protobuf = "4.33.1"

[plugins]
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
Expand All @@ -60,6 +61,7 @@ spotless = { id = "com.diffplug.spotless", version.ref = "spotless" }
detekt = { id = "io.gitlab.arturbosch.detekt", version = "1.23.8" }
jacoco-android = { id = "com.mxalbert.gradle.jacoco-android", version = "0.2.0" }
kover = { id = "org.jetbrains.kotlinx.kover", version = "0.7.3" }
protobuf = { id = "com.google.protobuf", version = "0.9.5" }
vanniktech-maven-publish = { id = "com.vanniktech.maven.publish", version = "0.30.0" }
springboot2 = { id = "org.springframework.boot", version.ref = "springboot2" }
springboot3 = { id = "org.springframework.boot", version.ref = "springboot3" }
Expand Down Expand Up @@ -138,6 +140,8 @@ otel-javaagent-extension-api = { module = "io.opentelemetry.javaagent:openteleme
otel-semconv = { module = "io.opentelemetry.semconv:opentelemetry-semconv", version.ref = "otelSemanticConventions" }
otel-semconv-incubating = { module = "io.opentelemetry.semconv:opentelemetry-semconv-incubating", version.ref = "otelSemanticConventionsAlpha" }
p6spy = { module = "p6spy:p6spy", version = "3.9.1" }
protobuf-javalite = { module = "com.google.protobuf:protobuf-javalite", version.ref = "protobuf"}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@romtsn Not sure if you followed the conversations, but as you can see here, protobuf requires a runtime dependency. It will have an impact of around 10kb. IMHO fine for now, we should still check how stable this library is to avoid and consumer version mismatch issues.

protoc = { module = "com.google.protobuf:protoc", version.ref = "protobuf" }
quartz = { module = "org.quartz-scheduler:quartz", version = "2.3.0" }
reactor-core = { module = "io.projectreactor:reactor-core", version = "3.5.3" }
retrofit = { module = "com.squareup.retrofit2:retrofit", version.ref = "retrofit" }
Expand Down
45 changes: 38 additions & 7 deletions sentry-android-core/api/sentry-android-core.api
Original file line number Diff line number Diff line change
Expand Up @@ -141,13 +141,6 @@ public final class io/sentry/android/core/AnrIntegrationFactory {
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 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
Expand Down Expand Up @@ -203,6 +196,13 @@ public final class io/sentry/android/core/AppState$LifecycleObserver : androidx/
public fun onStop (Landroidx/lifecycle/LifecycleOwner;)V
}

public final class io/sentry/android/core/ApplicationExitInfoEventProcessor : 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 final class io/sentry/android/core/BuildConfig {
public static final field BUILD_TYPE Ljava/lang/String;
public static final field DEBUG Z
Expand Down Expand Up @@ -351,6 +351,8 @@ public final class io/sentry/android/core/SentryAndroidOptions : io/sentry/Sentr
public fun isEnableSystemEventBreadcrumbs ()Z
public fun isEnableSystemEventBreadcrumbsExtras ()Z
public fun isReportHistoricalAnrs ()Z
public fun isReportHistoricalTombstones ()Z
public fun isTombstoneEnabled ()Z
public fun setAnrEnabled (Z)V
public fun setAnrReportInDebug (Z)V
public fun setAnrTimeoutIntervalMillis (J)V
Expand Down Expand Up @@ -379,6 +381,8 @@ public final class io/sentry/android/core/SentryAndroidOptions : io/sentry/Sentr
public fun setNativeHandlerStrategy (Lio/sentry/android/core/NdkHandlerStrategy;)V
public fun setNativeSdkName (Ljava/lang/String;)V
public fun setReportHistoricalAnrs (Z)V
public fun setReportHistoricalTombstones (Z)V
public fun setTombstoneEnabled (Z)V
}

public abstract interface class io/sentry/android/core/SentryAndroidOptions$BeforeCaptureCallback {
Expand Down Expand Up @@ -467,6 +471,29 @@ public final class io/sentry/android/core/SystemEventsBreadcrumbsIntegration : i
public fun register (Lio/sentry/IScopes;Lio/sentry/SentryOptions;)V
}

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

public final class io/sentry/android/core/TombstoneIntegration$TombstoneHint : io/sentry/hints/BlockingFlushHint, io/sentry/hints/Backfillable, io/sentry/hints/NativeCrashExit {
public fun <init> (JLio/sentry/ILogger;JZ)V
public fun isFlushable (Lio/sentry/protocol/SentryId;)Z
public fun setFlushable (Lio/sentry/protocol/SentryId;)V
public fun shouldEnrich ()Z
public fun timestamp ()Ljava/lang/Long;
}

public class io/sentry/android/core/TombstoneIntegration$TombstonePolicy : io/sentry/android/core/ApplicationExitInfoHistoryDispatcher$ApplicationExitInfoPolicy {
public fun <init> (Lio/sentry/android/core/SentryAndroidOptions;)V
public fun buildReport (Landroid/app/ApplicationExitInfo;Z)Lio/sentry/android/core/ApplicationExitInfoHistoryDispatcher$Report;
public fun getLabel ()Ljava/lang/String;
public fun getLastReportedTimestamp ()Ljava/lang/Long;
public fun getTargetReason ()I
public fun shouldReportHistorical ()Z
}

public final class io/sentry/android/core/UserInteractionIntegration : android/app/Application$ActivityLifecycleCallbacks, io/sentry/Integration, java/io/Closeable {
public fun <init> (Landroid/app/Application;Lio/sentry/util/LoadClass;)V
public fun close ()V
Expand All @@ -493,11 +520,15 @@ 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_MARKER_LABEL Ljava/lang/String;
public static final field LAST_ANR_REPORT Ljava/lang/String;
public static final field LAST_TOMBSTONE_MARKER_LABEL Ljava/lang/String;
public static final field LAST_TOMBSTONE_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 static fun lastReportedTombstone (Lio/sentry/SentryOptions;)Ljava/lang/Long;
public fun store (Lio/sentry/SentryEnvelope;Lio/sentry/Hint;)V
public fun storeEnvelope (Lio/sentry/SentryEnvelope;Lio/sentry/Hint;)Z
}
Expand Down
9 changes: 9 additions & 0 deletions sentry-android-core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ plugins {
alias(libs.plugins.jacoco.android)
alias(libs.plugins.errorprone)
alias(libs.plugins.gradle.versions)
alias(libs.plugins.protobuf)
}

android {
Expand Down Expand Up @@ -83,6 +84,7 @@ dependencies {
implementation(libs.androidx.lifecycle.common.java8)
implementation(libs.androidx.lifecycle.process)
implementation(libs.androidx.core)
implementation(libs.protobuf.javalite)

errorprone(libs.errorprone.core)
errorprone(libs.nopen.checker)
Expand All @@ -109,3 +111,10 @@ dependencies {
testRuntimeOnly(libs.androidx.fragment.ktx)
testRuntimeOnly(libs.timber)
}

protobuf {
protoc { artifact = libs.protoc.get().toString() }
generateProtoTasks {
all().forEach { task -> task.builtins { create("java") { option("lite") } } }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import android.app.Application;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.os.Build;
import io.sentry.CompositePerformanceCollector;
import io.sentry.DeduplicateMultithreadedEventProcessor;
import io.sentry.DefaultCompositePerformanceCollector;
Expand Down Expand Up @@ -188,7 +189,8 @@ 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.addEventProcessor(
new ApplicationExitInfoEventProcessor(context, options, buildInfoProvider));
if (options.getTransportGate() instanceof NoOpTransportGate) {
options.setTransportGate(new AndroidTransportGate(options));
}
Expand Down Expand Up @@ -373,6 +375,10 @@ static void installDefaultIntegrations(
final Class<?> sentryNdkClass = loadClass.loadClass(SENTRY_NDK_CLASS_NAME, options.getLogger());
options.addIntegration(new NdkIntegration(sentryNdkClass));

if (buildInfoProvider.getSdkInfoVersion() >= Build.VERSION_CODES.S) {
options.addIntegration(new TombstoneIntegration(context));
}

// this integration uses android.os.FileObserver, we can't move to sentry
// before creating a pure java impl.
options.addIntegration(EnvelopeFileObserverIntegration.getOutboxFileObserver());
Expand Down
Loading
Loading