From 6120468a0546af9e77141676e230d63e08fc7d90 Mon Sep 17 00:00:00 2001 From: GIancarlo Buenaflor Date: Fri, 27 Sep 2024 23:51:44 +0200 Subject: [PATCH] add replay options --- .../SentryOptionsExtensions.android.kt | 6 +++ .../kotlin/multiplatform/SentryOptions.kt | 17 +++++++++ .../multiplatform/SessionReplayOptions.kt | 37 +++++++++++++++++++ .../multiplatform/SentryIntegrationTest.kt | 7 +--- .../extensions/SentryOptionsExtensions.ios.kt | 28 +++++++++++--- 5 files changed, 83 insertions(+), 12 deletions(-) create mode 100644 sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SessionReplayOptions.kt diff --git a/sentry-kotlin-multiplatform/src/androidMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.android.kt b/sentry-kotlin-multiplatform/src/androidMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.android.kt index 02fa5a96..da6d3448 100644 --- a/sentry-kotlin-multiplatform/src/androidMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.android.kt +++ b/sentry-kotlin-multiplatform/src/androidMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.android.kt @@ -14,6 +14,12 @@ internal fun SentryOptions.toAndroidSentryOptionsCallback(): (SentryAndroidOptio it.isAnrEnabled = this.isAnrEnabled it.anrTimeoutIntervalMillis = this.anrTimeoutIntervalMillis + // Replay options + it.experimental.sessionReplay.redactAllText = this.experimental.sessionReplay.redactAllText + it.experimental.sessionReplay.redactAllImages = this.experimental.sessionReplay.redactAllImages + it.experimental.sessionReplay.sessionSampleRate = this.experimental.sessionReplay.sessionSampleRate?.toDouble() + it.experimental.sessionReplay.errorSampleRate = this.experimental.sessionReplay.onErrorSampleRate?.toDouble() + // kForEach solves an issue with linter where it thinks forEach is the Java version // see here: https://stackoverflow.com/questions/44751469/kotlin-extension-functions-suddenly-require-api-level-24/68897591#68897591 this.sdk?.packages?.kForEach { sdkPackage -> 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 9abb506b..d0687ce9 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 @@ -171,4 +171,21 @@ public open class SentryOptions { * [Android ANR](https://docs.sentry.io/platforms/android/configuration/app-not-respond/) */ public var anrTimeoutIntervalMillis: Long = DEFAULT_ANR_TIMEOUT_INTERVAL_MILLIS + + public var experimental: ExperimentalOptions = ExperimentalOptions() + private set + + /** + * Experimental options for new features, these options are going to be promoted to SentryOptions + * before GA. + * + * Beware that experimental options can change at any time. + */ + public class ExperimentalOptions { + /** + * Experimental feature. The options for session replay. + * Currently available for **Android** and **iOS**. + */ + public var sessionReplay: SentryReplayOptions = SentryReplayOptions() + } } diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SessionReplayOptions.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SessionReplayOptions.kt new file mode 100644 index 00000000..6df1c3ac --- /dev/null +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SessionReplayOptions.kt @@ -0,0 +1,37 @@ +package io.sentry.kotlin.multiplatform + +/** + * Configuration options for session replay. + */ +public data class SentryReplayOptions( + /** + * Indicates the percentage in which the replay for the session will be created. + * Specifying 0 means never, 1.0 means always. The value needs to be >= 0.0 and <= 1.0. + * + * The default is null (disabled). + */ + public var sessionSampleRate: Double? = null, + + /** + * Indicates the percentage in which a 30 seconds replay will be sent with error events. + * Specifying 0 means never, 1.0 means always. The value needs to be >= 0.0 and <= 1.0. + * + * The default is null (disabled). + */ + public var onErrorSampleRate: Double? = null, + + /** + * Redact all text content. Draws a rectangle of text bounds with text color on top. + * + * The default is true. + */ + public var redactAllText: Boolean = true, + + /** + * Redact all image content. Draws a rectangle of image bounds with image's dominant color on top. + * + * The default is true. + */ + public var redactAllImages: Boolean = true, +) + diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryIntegrationTest.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryIntegrationTest.kt index 9cb7a8b0..d5e569d1 100644 --- a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryIntegrationTest.kt +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryIntegrationTest.kt @@ -4,12 +4,7 @@ import io.sentry.kotlin.multiplatform.protocol.Breadcrumb import io.sentry.kotlin.multiplatform.protocol.User import io.sentry.kotlin.multiplatform.utils.fakeDsn import kotlinx.coroutines.test.runTest -import kotlin.test.AfterTest -import kotlin.test.Test -import kotlin.test.assertEquals -import kotlin.test.assertNotEquals -import kotlin.test.assertNotNull -import kotlin.test.assertTrue +import kotlin.test.* class SentryIntegrationTest : BaseSentryTest() { @AfterTest diff --git a/sentry-kotlin-multiplatform/src/iosMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.ios.kt b/sentry-kotlin-multiplatform/src/iosMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.ios.kt index bb7638d1..7077f128 100644 --- a/sentry-kotlin-multiplatform/src/iosMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.ios.kt +++ b/sentry-kotlin-multiplatform/src/iosMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.ios.kt @@ -3,11 +3,27 @@ package io.sentry.kotlin.multiplatform.extensions import io.sentry.kotlin.multiplatform.CocoaSentryOptions import io.sentry.kotlin.multiplatform.SentryOptions -internal fun SentryOptions.toIosOptionsConfiguration(): (CocoaSentryOptions?) -> Unit = { - // Apply base options available to all Cocoa/Apple targets - it?.applyCocoaBaseOptions(this) +internal fun SentryOptions.toIosOptionsConfiguration(): (CocoaSentryOptions?) -> Unit = { options -> + options?.let { cocoaOptions -> + val kmpOptions = this@toIosOptionsConfiguration - // Apply iOS specific options - it?.attachScreenshot = this.attachScreenshot - it?.attachViewHierarchy = this.attachViewHierarchy + // Apply base options available to all Cocoa/Apple targets + cocoaOptions.applyCocoaBaseOptions(kmpOptions) + + // Apply iOS specific options + cocoaOptions.attachScreenshot = this.attachScreenshot + cocoaOptions.attachViewHierarchy = this.attachViewHierarchy + + // Replay options + cocoaOptions.experimental.sessionReplay().apply { + setRedactAllText(kmpOptions.experimental.sessionReplay.redactAllText) + setRedactAllImages(kmpOptions.experimental.sessionReplay.redactAllImages) + kmpOptions.experimental.sessionReplay.sessionSampleRate?.let { setSessionSampleRate(it.toFloat()) } + kmpOptions.experimental.sessionReplay.onErrorSampleRate?.let { setOnErrorSampleRate(it.toFloat()) } + } + } ?: run { + // Log a warning if options is null + // TODO: Replace with actual logging when a logger is available + println("Warning: CocoaSentryOptions is null, skipping iOS configuration") + } }