From 1bf5cc1a8889b9bd88a3a0866a33cd0068c82a35 Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Wed, 9 Oct 2024 01:01:29 +0200 Subject: [PATCH] Expose `enableWatchdogTerminationTracking` in common options (#281) * update * update * format * update * Update CHANGELOG.md * update --- CHANGELOG.md | 1 + .../android/sentry-kotlin-multiplatform.api | 2 + .../api/jvm/sentry-kotlin-multiplatform.api | 2 + .../SentryOptionsExtensions.apple.kt | 58 +++++++------- .../multiplatform/PlatformOptions.apple.kt | 76 +++++++++++++++++++ .../kotlin/multiplatform/SentryOptions.kt | 10 +++ .../kotlin/multiplatform/SentryOptionsTest.kt | 4 +- .../PlatformOptions.tvwatchmacos.kt | 57 +------------- .../multiplatform/PlatformOptions.ios.kt | 50 +----------- 9 files changed, 132 insertions(+), 128 deletions(-) create mode 100644 sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/PlatformOptions.apple.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index fab46fd6..06622ead 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ Sentry.init { options -> } ``` - Add `Sentry.isEnabled()` API to common code ([#273](https://github.com/getsentry/sentry-kotlin-multiplatform/pull/273)) +- Add `enableWatchdogTerminationTracking` in common options ([#281](https://github.com/getsentry/sentry-kotlin-multiplatform/pull/281)) ### Dependencies diff --git a/sentry-kotlin-multiplatform/api/android/sentry-kotlin-multiplatform.api b/sentry-kotlin-multiplatform/api/android/sentry-kotlin-multiplatform.api index c923f788..7faedcaf 100644 --- a/sentry-kotlin-multiplatform/api/android/sentry-kotlin-multiplatform.api +++ b/sentry-kotlin-multiplatform/api/android/sentry-kotlin-multiplatform.api @@ -174,6 +174,7 @@ public class io/sentry/kotlin/multiplatform/SentryOptions { public final fun getEnableAppHangTracking ()Z public final fun getEnableAutoSessionTracking ()Z public final fun getEnableCaptureFailedRequests ()Z + public final fun getEnableWatchdogTerminationTracking ()Z public final fun getEnvironment ()Ljava/lang/String; public final fun getExperimental ()Lio/sentry/kotlin/multiplatform/SentryOptions$ExperimentalOptions; public final fun getFailedRequestStatusCodes ()Ljava/util/List; @@ -201,6 +202,7 @@ public class io/sentry/kotlin/multiplatform/SentryOptions { public final fun setEnableAppHangTracking (Z)V public final fun setEnableAutoSessionTracking (Z)V public final fun setEnableCaptureFailedRequests (Z)V + public final fun setEnableWatchdogTerminationTracking (Z)V public final fun setEnvironment (Ljava/lang/String;)V public final fun setFailedRequestStatusCodes (Ljava/util/List;)V public final fun setFailedRequestTargets (Ljava/util/List;)V diff --git a/sentry-kotlin-multiplatform/api/jvm/sentry-kotlin-multiplatform.api b/sentry-kotlin-multiplatform/api/jvm/sentry-kotlin-multiplatform.api index d36e48fa..97ad6f0b 100644 --- a/sentry-kotlin-multiplatform/api/jvm/sentry-kotlin-multiplatform.api +++ b/sentry-kotlin-multiplatform/api/jvm/sentry-kotlin-multiplatform.api @@ -171,6 +171,7 @@ public class io/sentry/kotlin/multiplatform/SentryOptions { public final fun getEnableAppHangTracking ()Z public final fun getEnableAutoSessionTracking ()Z public final fun getEnableCaptureFailedRequests ()Z + public final fun getEnableWatchdogTerminationTracking ()Z public final fun getEnvironment ()Ljava/lang/String; public final fun getExperimental ()Lio/sentry/kotlin/multiplatform/SentryOptions$ExperimentalOptions; public final fun getFailedRequestStatusCodes ()Ljava/util/List; @@ -198,6 +199,7 @@ public class io/sentry/kotlin/multiplatform/SentryOptions { public final fun setEnableAppHangTracking (Z)V public final fun setEnableAutoSessionTracking (Z)V public final fun setEnableCaptureFailedRequests (Z)V + public final fun setEnableWatchdogTerminationTracking (Z)V public final fun setEnvironment (Ljava/lang/String;)V public final fun setFailedRequestStatusCodes (Ljava/util/List;)V public final fun setFailedRequestTargets (Ljava/util/List;)V diff --git a/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.apple.kt b/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.apple.kt index 91361d3b..aac8aeff 100644 --- a/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.apple.kt +++ b/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.apple.kt @@ -15,31 +15,33 @@ internal fun SentryOptions.toCocoaOptionsConfiguration(): (CocoaSentryOptions?) * Applies the given options to this CocoaSentryOptions. * This avoids code duplication for init on iOS. */ -internal fun CocoaSentryOptions.applyCocoaBaseOptions(options: SentryOptions) { - dsn = options.dsn - attachStacktrace = options.attachStackTrace - dist = options.dist - options.environment?.let { - environment = it +internal fun CocoaSentryOptions.applyCocoaBaseOptions(kmpOptions: SentryOptions) { + val cocoaOptions = this + cocoaOptions.dsn = kmpOptions.dsn + cocoaOptions.attachStacktrace = kmpOptions.attachStackTrace + cocoaOptions.dist = kmpOptions.dist + kmpOptions.environment?.let { + cocoaOptions.environment = it } - releaseName = options.release - debug = options.debug - sessionTrackingIntervalMillis = options.sessionTrackingIntervalMillis.convert() - enableAutoSessionTracking = options.enableAutoSessionTracking - maxAttachmentSize = options.maxAttachmentSize.convert() - maxBreadcrumbs = options.maxBreadcrumbs.convert() - enableAppHangTracking = options.enableAppHangTracking - appHangTimeoutInterval = options.appHangTimeoutIntervalMillis.toDouble() - options.sampleRate?.let { - sampleRate = NSNumber(double = it) + cocoaOptions.releaseName = kmpOptions.release + cocoaOptions.debug = kmpOptions.debug + cocoaOptions.sessionTrackingIntervalMillis = kmpOptions.sessionTrackingIntervalMillis.convert() + cocoaOptions.enableAutoSessionTracking = kmpOptions.enableAutoSessionTracking + cocoaOptions.maxAttachmentSize = kmpOptions.maxAttachmentSize.convert() + cocoaOptions.maxBreadcrumbs = kmpOptions.maxBreadcrumbs.convert() + cocoaOptions.enableAppHangTracking = kmpOptions.enableAppHangTracking + cocoaOptions.enableWatchdogTerminationTracking = kmpOptions.enableWatchdogTerminationTracking + cocoaOptions.appHangTimeoutInterval = kmpOptions.appHangTimeoutIntervalMillis.toDouble() + kmpOptions.sampleRate?.let { + cocoaOptions.sampleRate = NSNumber(double = it) } - options.tracesSampleRate?.let { - tracesSampleRate = NSNumber(double = it) + kmpOptions.tracesSampleRate?.let { + cocoaOptions.tracesSampleRate = NSNumber(double = it) } - beforeSend = { event -> + cocoaOptions.beforeSend = { event -> val sdk = event?.sdk?.toMutableMap() - val packages = options.sdk?.packages?.map { + val packages = kmpOptions.sdk?.packages?.map { mapOf("name" to it.name, "version" to it.version) }?.toMutableList() ?: mutableListOf() @@ -47,28 +49,28 @@ internal fun CocoaSentryOptions.applyCocoaBaseOptions(options: SentryOptions) { event?.sdk = sdk - if (options.beforeSend == null) { + if (kmpOptions.beforeSend == null) { event } else { event?.let { SentryEvent(it) }?.let { unwrappedEvent -> - val result = options.beforeSend?.invoke(unwrappedEvent) + val result = kmpOptions.beforeSend?.invoke(unwrappedEvent) result?.let { event.applyKmpEvent(it) } } } } - beforeBreadcrumb = { cocoaBreadcrumb -> - if (options.beforeBreadcrumb == null) { + cocoaOptions.beforeBreadcrumb = { cocoaBreadcrumb -> + if (kmpOptions.beforeBreadcrumb == null) { cocoaBreadcrumb } else { cocoaBreadcrumb?.toKmpBreadcrumb() - ?.let { options.beforeBreadcrumb?.invoke(it) }?.toCocoaBreadcrumb() + ?.let { kmpOptions.beforeBreadcrumb?.invoke(it) }?.toCocoaBreadcrumb() } } - enableCaptureFailedRequests = options.enableCaptureFailedRequests - failedRequestTargets = options.failedRequestTargets - failedRequestStatusCodes = options.failedRequestStatusCodes.map { + cocoaOptions.enableCaptureFailedRequests = kmpOptions.enableCaptureFailedRequests + cocoaOptions.failedRequestTargets = kmpOptions.failedRequestTargets + cocoaOptions.failedRequestStatusCodes = kmpOptions.failedRequestStatusCodes.map { SentryHttpStatusCodeRange( min = it.min.convert(), max = it.max.convert() diff --git a/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/PlatformOptions.apple.kt b/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/PlatformOptions.apple.kt new file mode 100644 index 00000000..015fe560 --- /dev/null +++ b/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/PlatformOptions.apple.kt @@ -0,0 +1,76 @@ +package io.sentry.kotlin.multiplatform + +import io.sentry.kotlin.multiplatform.extensions.toCocoaOptionsConfiguration +import io.sentry.kotlin.multiplatform.utils.fakeDsn +import kotlinx.cinterop.convert +import kotlin.test.assertEquals + +actual interface PlatformOptions : CommonPlatformOptions { + val enableWatchdogTerminationTracking: Boolean +} + +open class SentryAppleOptionsWrapper(private val cocoaOptions: CocoaSentryOptions) : + PlatformOptions { + override val dsn: String? + get() = cocoaOptions.dsn + + override val attachStackTrace: Boolean + get() = cocoaOptions.attachStacktrace + + override val release: String? + get() = cocoaOptions.releaseName + + override val debug: Boolean + get() = cocoaOptions.debug + + override val environment: String + get() = cocoaOptions.environment + + override val dist: String? + get() = cocoaOptions.dist + + override val enableAutoSessionTracking: Boolean + get() = cocoaOptions.enableAutoSessionTracking + + override val sessionTrackingIntervalMillis: Long + get() = cocoaOptions.sessionTrackingIntervalMillis.convert() + + override val maxBreadcrumbs: Int + get() = cocoaOptions.maxBreadcrumbs.convert() + + override val maxAttachmentSize: Long + get() = cocoaOptions.maxAttachmentSize.convert() + + override val sampleRate: Double? + get() = cocoaOptions.sampleRate?.doubleValue + + override val tracesSampleRate: Double? + get() = cocoaOptions.tracesSampleRate?.doubleValue + + override val enableWatchdogTerminationTracking: Boolean + get() = cocoaOptions.enableWatchdogTerminationTracking + + override fun applyFromOptions(options: SentryOptions) { + options.toCocoaOptionsConfiguration().invoke(cocoaOptions) + } +} + +expect interface ApplePlatformOptions : PlatformOptions + +actual fun createPlatformOptions(): PlatformOptions = createApplePlatformOptions() + +expect fun createApplePlatformOptions(): PlatformOptions + +expect fun ApplePlatformOptions.assertApplePlatformSpecificOptions(options: SentryOptions) + +actual fun PlatformOptions.assertPlatformSpecificOptions(options: SentryOptions) { + (this as ApplePlatformOptions).assertApplePlatformSpecificOptions(options) + + val appleOptions = this + assertEquals(appleOptions.enableWatchdogTerminationTracking, options.enableWatchdogTerminationTracking) +} + +actual fun createSentryPlatformOptionsConfiguration(): PlatformOptionsConfiguration = { + val cocoaOptions = it as CocoaSentryOptions + cocoaOptions.dsn = fakeDsn +} diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryOptions.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryOptions.kt index f480b422..2d8df290 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryOptions.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryOptions.kt @@ -172,6 +172,16 @@ public open class SentryOptions { */ public var anrTimeoutIntervalMillis: Long = DEFAULT_ANR_TIMEOUT_INTERVAL_MILLIS + /** + * Whether to enable Watchdog Termination tracking or not. + * + * **Default**: Enabled. + * + * **Platform Availability**: Cocoa. + * + */ + public var enableWatchdogTerminationTracking: Boolean = true + /** * Experimental options for new features, these options are going to be promoted to SentryOptions * before GA. diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryOptionsTest.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryOptionsTest.kt index 4ea76a6e..d3379b90 100644 --- a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryOptionsTest.kt +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryOptionsTest.kt @@ -131,10 +131,11 @@ class SentryOptionsTest : BaseSentryTest() { assertTrue(options.experimental.sessionReplay.redactAllText) assertTrue(options.experimental.sessionReplay.redactAllImages) assertEquals(SentryReplayOptions.Quality.MEDIUM, options.experimental.sessionReplay.quality) + assertTrue(options.enableWatchdogTerminationTracking) } @Test - fun `GIVEN SentryOptions WHEN applyFromOptions THEN applies values to native options`() { + fun `GIVEN non-default SentryOptions WHEN options initialized THEN applies values to native options`() { val options = SentryOptions().apply { dsn = fakeDsn attachStackTrace = false @@ -154,6 +155,7 @@ class SentryOptionsTest : BaseSentryTest() { appHangTimeoutIntervalMillis = 1000L isAnrEnabled = false anrTimeoutIntervalMillis = 1000L + enableWatchdogTerminationTracking = false experimental.sessionReplay.onErrorSampleRate = 0.5 experimental.sessionReplay.sessionSampleRate = 0.5 experimental.sessionReplay.redactAllText = false diff --git a/sentry-kotlin-multiplatform/src/commonTvWatchMacOsTest/kotlin/io/sentry/kotlin/multiplatform/PlatformOptions.tvwatchmacos.kt b/sentry-kotlin-multiplatform/src/commonTvWatchMacOsTest/kotlin/io/sentry/kotlin/multiplatform/PlatformOptions.tvwatchmacos.kt index 3cc87d35..bc3e1a65 100644 --- a/sentry-kotlin-multiplatform/src/commonTvWatchMacOsTest/kotlin/io/sentry/kotlin/multiplatform/PlatformOptions.tvwatchmacos.kt +++ b/sentry-kotlin-multiplatform/src/commonTvWatchMacOsTest/kotlin/io/sentry/kotlin/multiplatform/PlatformOptions.tvwatchmacos.kt @@ -1,61 +1,12 @@ package io.sentry.kotlin.multiplatform -import io.sentry.kotlin.multiplatform.extensions.toCocoaOptionsConfiguration -import io.sentry.kotlin.multiplatform.utils.fakeDsn -import kotlinx.cinterop.convert +actual interface ApplePlatformOptions : PlatformOptions -actual interface PlatformOptions : CommonPlatformOptions +class SentryTvWatchMacOsOptionsWrapper(cocoaOptions: CocoaSentryOptions) : SentryAppleOptionsWrapper(cocoaOptions) -class SentryTvWatchMacOsOptionsWrapper(private val cocoaOptions: CocoaSentryOptions) : - PlatformOptions { - override val dsn: String? - get() = cocoaOptions.dsn - - override val attachStackTrace: Boolean - get() = cocoaOptions.attachStacktrace - - override val release: String? - get() = cocoaOptions.releaseName - - override val debug: Boolean - get() = cocoaOptions.debug - - override val environment: String - get() = cocoaOptions.environment - - override val dist: String? - get() = cocoaOptions.dist - - override val enableAutoSessionTracking: Boolean - get() = cocoaOptions.enableAutoSessionTracking - - override val sessionTrackingIntervalMillis: Long - get() = cocoaOptions.sessionTrackingIntervalMillis.convert() - - override val maxBreadcrumbs: Int - get() = cocoaOptions.maxBreadcrumbs.convert() - - override val maxAttachmentSize: Long - get() = cocoaOptions.maxAttachmentSize.convert() - - override val sampleRate: Double? - get() = cocoaOptions.sampleRate?.doubleValue - - override val tracesSampleRate: Double? - get() = cocoaOptions.tracesSampleRate?.doubleValue - - override fun applyFromOptions(options: SentryOptions) { - options.toCocoaOptionsConfiguration().invoke(cocoaOptions) - } -} - -actual fun createPlatformOptions(): PlatformOptions = +actual fun createApplePlatformOptions(): PlatformOptions = SentryTvWatchMacOsOptionsWrapper(CocoaSentryOptions()) -actual fun PlatformOptions.assertPlatformSpecificOptions(options: SentryOptions) { +actual fun ApplePlatformOptions.assertApplePlatformSpecificOptions(options: SentryOptions) { // no-op } - -actual fun createSentryPlatformOptionsConfiguration(): PlatformOptionsConfiguration = { - it.dsn = fakeDsn -} diff --git a/sentry-kotlin-multiplatform/src/iosTest/kotlin/io/sentry/kotlin/multiplatform/PlatformOptions.ios.kt b/sentry-kotlin-multiplatform/src/iosTest/kotlin/io/sentry/kotlin/multiplatform/PlatformOptions.ios.kt index 3c3c4f19..a9a7b021 100644 --- a/sentry-kotlin-multiplatform/src/iosTest/kotlin/io/sentry/kotlin/multiplatform/PlatformOptions.ios.kt +++ b/sentry-kotlin-multiplatform/src/iosTest/kotlin/io/sentry/kotlin/multiplatform/PlatformOptions.ios.kt @@ -2,11 +2,9 @@ package io.sentry.kotlin.multiplatform import cocoapods.Sentry.SentryReplayOptions import io.sentry.kotlin.multiplatform.extensions.toIosOptionsConfiguration -import io.sentry.kotlin.multiplatform.utils.fakeDsn -import kotlinx.cinterop.convert import kotlin.test.assertEquals -actual interface PlatformOptions : CommonPlatformOptions { +actual interface ApplePlatformOptions : PlatformOptions { val attachScreenshot: Boolean val attachViewHierarchy: Boolean val enableAppHangTracking: Boolean @@ -14,7 +12,7 @@ actual interface PlatformOptions : CommonPlatformOptions { val sessionReplay: SentryReplayOptions } -class SentryIosOptionsWrapper(private val cocoaOptions: CocoaSentryOptions) : PlatformOptions { +class SentryIosOptionsWrapper(private val cocoaOptions: CocoaSentryOptions) : SentryAppleOptionsWrapper(cocoaOptions), ApplePlatformOptions { override val attachScreenshot: Boolean get() = cocoaOptions.attachScreenshot @@ -27,42 +25,6 @@ class SentryIosOptionsWrapper(private val cocoaOptions: CocoaSentryOptions) : Pl override val appHangTimeoutIntervalMillis: Long get() = cocoaOptions.appHangTimeoutInterval.toLong() - override val dsn: String? - get() = cocoaOptions.dsn - - override val attachStackTrace: Boolean - get() = cocoaOptions.attachStacktrace - - override val release: String? - get() = cocoaOptions.releaseName - - override val debug: Boolean - get() = cocoaOptions.debug - - override val environment: String - get() = cocoaOptions.environment - - override val dist: String? - get() = cocoaOptions.dist - - override val enableAutoSessionTracking: Boolean - get() = cocoaOptions.enableAutoSessionTracking - - override val sessionTrackingIntervalMillis: Long - get() = cocoaOptions.sessionTrackingIntervalMillis.convert() - - override val maxBreadcrumbs: Int - get() = cocoaOptions.maxBreadcrumbs.convert() - - override val maxAttachmentSize: Long - get() = cocoaOptions.maxAttachmentSize.convert() - - override val sampleRate: Double? - get() = cocoaOptions.sampleRate?.doubleValue - - override val tracesSampleRate: Double? - get() = cocoaOptions.tracesSampleRate?.doubleValue - override val sessionReplay: SentryReplayOptions get() = cocoaOptions.experimental.sessionReplay() @@ -71,9 +33,9 @@ class SentryIosOptionsWrapper(private val cocoaOptions: CocoaSentryOptions) : Pl } } -actual fun createPlatformOptions(): PlatformOptions = SentryIosOptionsWrapper(CocoaSentryOptions()) +actual fun createApplePlatformOptions(): PlatformOptions = SentryIosOptionsWrapper(CocoaSentryOptions()) -actual fun PlatformOptions.assertPlatformSpecificOptions(options: SentryOptions) { +actual fun ApplePlatformOptions.assertApplePlatformSpecificOptions(options: SentryOptions) { assertEquals(attachScreenshot, options.attachScreenshot) assertEquals(attachViewHierarchy, options.attachViewHierarchy) assertEquals(enableAppHangTracking, options.enableAppHangTracking) @@ -84,7 +46,3 @@ actual fun PlatformOptions.assertPlatformSpecificOptions(options: SentryOptions) assertEquals(sessionReplay.sessionSampleRate().toDouble(), options.experimental.sessionReplay.sessionSampleRate) assertEquals(sessionReplay.quality(), options.experimental.sessionReplay.quality.ordinal.toLong()) } - -actual fun createSentryPlatformOptionsConfiguration(): PlatformOptionsConfiguration = { - it.dsn = fakeDsn -}