Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

### Features

- Add App Hang Tracking / ANR options ([#187](https://github.com/getsentry/sentry-kotlin-multiplatform/pull/187))
- Use `isAnrEnabled` and `anrTimeoutIntervalMillis` to configure ANR tracking for Android
- Use `enableAppHangTracking` and `appHangTimeoutIntervalMillis` to configure App Hang tracking for iOS
- Both options are enabled by default
- Add isCrashedLastRun ([#186](https://github.com/getsentry/sentry-kotlin-multiplatform/pull/186))
- You can use it with `Sentry.isCrashedLastRun()`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,8 @@ public final class io/sentry/kotlin/multiplatform/SentryLevel : java/lang/Enum {

public class io/sentry/kotlin/multiplatform/SentryOptions {
public fun <init> ()V
public final fun getAnrTimeoutIntervalMillis ()J
public final fun getAppHangTimeoutIntervalMillis ()J
public final fun getAttachScreenshot ()Z
public final fun getAttachStackTrace ()Z
public final fun getAttachThreads ()Z
Expand All @@ -167,6 +169,7 @@ public class io/sentry/kotlin/multiplatform/SentryOptions {
public final fun getDebug ()Z
public final fun getDist ()Ljava/lang/String;
public final fun getDsn ()Ljava/lang/String;
public final fun getEnableAppHangTracking ()Z
public final fun getEnableAutoSessionTracking ()Z
public final fun getEnableCaptureFailedRequests ()Z
public final fun getEnvironment ()Ljava/lang/String;
Expand All @@ -179,6 +182,10 @@ public class io/sentry/kotlin/multiplatform/SentryOptions {
public final fun getSdk ()Lio/sentry/kotlin/multiplatform/protocol/SdkVersion;
public final fun getSessionTrackingIntervalMillis ()J
public final fun getTracesSampleRate ()Ljava/lang/Double;
public final fun isAnrEnabled ()Z
public final fun setAnrEnabled (Z)V
public final fun setAnrTimeoutIntervalMillis (J)V
public final fun setAppHangTimeoutIntervalMillis (J)V
public final fun setAttachScreenshot (Z)V
public final fun setAttachStackTrace (Z)V
public final fun setAttachThreads (Z)V
Expand All @@ -188,6 +195,7 @@ public class io/sentry/kotlin/multiplatform/SentryOptions {
public final fun setDebug (Z)V
public final fun setDist (Ljava/lang/String;)V
public final fun setDsn (Ljava/lang/String;)V
public final fun setEnableAppHangTracking (Z)V
public final fun setEnableAutoSessionTracking (Z)V
public final fun setEnableCaptureFailedRequests (Z)V
public final fun setEnvironment (Ljava/lang/String;)V
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,8 @@ public final class io/sentry/kotlin/multiplatform/SentryLevel : java/lang/Enum {

public class io/sentry/kotlin/multiplatform/SentryOptions {
public fun <init> ()V
public final fun getAnrTimeoutIntervalMillis ()J
public final fun getAppHangTimeoutIntervalMillis ()J
public final fun getAttachScreenshot ()Z
public final fun getAttachStackTrace ()Z
public final fun getAttachThreads ()Z
Expand All @@ -164,6 +166,7 @@ public class io/sentry/kotlin/multiplatform/SentryOptions {
public final fun getDebug ()Z
public final fun getDist ()Ljava/lang/String;
public final fun getDsn ()Ljava/lang/String;
public final fun getEnableAppHangTracking ()Z
public final fun getEnableAutoSessionTracking ()Z
public final fun getEnableCaptureFailedRequests ()Z
public final fun getEnvironment ()Ljava/lang/String;
Expand All @@ -176,6 +179,10 @@ public class io/sentry/kotlin/multiplatform/SentryOptions {
public final fun getSdk ()Lio/sentry/kotlin/multiplatform/protocol/SdkVersion;
public final fun getSessionTrackingIntervalMillis ()J
public final fun getTracesSampleRate ()Ljava/lang/Double;
public final fun isAnrEnabled ()Z
public final fun setAnrEnabled (Z)V
public final fun setAnrTimeoutIntervalMillis (J)V
public final fun setAppHangTimeoutIntervalMillis (J)V
public final fun setAttachScreenshot (Z)V
public final fun setAttachStackTrace (Z)V
public final fun setAttachThreads (Z)V
Expand All @@ -185,6 +192,7 @@ public class io/sentry/kotlin/multiplatform/SentryOptions {
public final fun setDebug (Z)V
public final fun setDist (Ljava/lang/String;)V
public final fun setDsn (Ljava/lang/String;)V
public final fun setEnableAppHangTracking (Z)V
public final fun setEnableAutoSessionTracking (Z)V
public final fun setEnableCaptureFailedRequests (Z)V
public final fun setEnvironment (Ljava/lang/String;)V
Expand Down
8 changes: 8 additions & 0 deletions sentry-kotlin-multiplatform/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,14 @@ kotlin {
macosMain.get().dependsOn(commonTvWatchMacOsMain)
watchosMain.get().dependsOn(commonTvWatchMacOsMain)

val commonTvWatchMacOsTest by creating {
dependsOn(appleTest.get())
}

tvosTest.get().dependsOn(commonTvWatchMacOsTest)
macosTest.get().dependsOn(commonTvWatchMacOsTest)
watchosTest.get().dependsOn(commonTvWatchMacOsTest)

cocoapods {
summary = "Official Sentry SDK Kotlin Multiplatform"
homepage = "https://github.com/getsentry/sentry-kotlin-multiplatform"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,4 @@ Pod::Spec.new do |spec|
}
]

end
end
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ internal fun SentryOptions.toAndroidSentryOptionsCallback(): (SentryAndroidOptio
// Apply Android specific options
it.isAttachScreenshot = this.attachScreenshot
it.isAttachViewHierarchy = this.attachViewHierarchy
it.isAnrEnabled = this.isAnrEnabled
it.anrTimeoutIntervalMillis = this.anrTimeoutIntervalMillis

it.sdkVersion?.name = this.sdk?.name ?: BuildKonfig.SENTRY_KMP_ANDROID_SDK_NAME
it.sdkVersion?.version = this.sdk?.version ?: BuildKonfig.VERSION_NAME
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package io.sentry.kotlin.multiplatform

import io.sentry.android.core.SentryAndroidOptions
import io.sentry.kotlin.multiplatform.extensions.toAndroidSentryOptionsCallback
import kotlin.test.assertEquals

actual interface PlatformOptions : CommonPlatformOptions {
val isAnrEnabled: Boolean
val anrTimeoutIntervalMillis: Long
val attachScreenshot: Boolean
val attachViewHierarchy: Boolean
}

class SentryAndroidOptionsWrapper(private val androidOptions: SentryAndroidOptions) :
PlatformOptions {
override val dsn: String?
get() = androidOptions.dsn

override val attachStackTrace: Boolean
get() = androidOptions.isAttachStacktrace

override val release: String?
get() = androidOptions.release

override val debug: Boolean
get() = androidOptions.isDebug

override val environment: String?
get() = androidOptions.environment

override val dist: String?
get() = androidOptions.dist

override val enableAutoSessionTracking: Boolean
get() = androidOptions.isEnableAutoSessionTracking

override val sessionTrackingIntervalMillis: Long
get() = androidOptions.sessionTrackingIntervalMillis

override val maxBreadcrumbs: Int
get() = androidOptions.maxBreadcrumbs

override val maxAttachmentSize: Long
get() = androidOptions.maxAttachmentSize

override val sampleRate: Double?
get() = androidOptions.sampleRate

override val tracesSampleRate: Double?
get() = androidOptions.tracesSampleRate

override val isAnrEnabled: Boolean
get() = androidOptions.isAnrEnabled

override val anrTimeoutIntervalMillis: Long
get() = androidOptions.anrTimeoutIntervalMillis

override val attachScreenshot: Boolean
get() = androidOptions.isAttachScreenshot

override val attachViewHierarchy: Boolean
get() = androidOptions.isAttachViewHierarchy

override fun applyFromOptions(options: SentryOptions) {
options.toAndroidSentryOptionsCallback().invoke(androidOptions)
}
}

actual fun createPlatformOptions(): PlatformOptions =
SentryAndroidOptionsWrapper(SentryAndroidOptions())

actual fun PlatformOptions.assertPlatformSpecificOptions(options: SentryOptions) {
assertEquals(attachScreenshot, options.attachScreenshot)
assertEquals(attachViewHierarchy, options.attachViewHierarchy)
assertEquals(isAnrEnabled, options.isAnrEnabled)
assertEquals(anrTimeoutIntervalMillis, options.anrTimeoutIntervalMillis)
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ internal fun CocoaSentryOptions.applyCocoaBaseOptions(options: SentryOptions) {
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)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ package io.sentry.kotlin.multiplatform
import io.sentry.kotlin.multiplatform.protocol.Breadcrumb
import io.sentry.kotlin.multiplatform.protocol.SdkVersion

private const val DEFAULT_MAX_BREADCRUMBS = 100
private const val DEFAULT_MAX_ATTACHMENT_SIZE = 20 * 1024 * 1024L
private const val DEFAULT_SESSION_INTERVAL_MILLIS = 30000L
internal const val DEFAULT_MAX_BREADCRUMBS = 100
internal const val DEFAULT_MAX_ATTACHMENT_SIZE = 20 * 1024 * 1024L
internal const val DEFAULT_SESSION_INTERVAL_MILLIS = 30000L
internal const val DEFAULT_APPHANG_TIMEOUT_INTERVAL_MILLIS = 2000L
internal const val DEFAULT_ANR_TIMEOUT_INTERVAL_MILLIS = 5000L

/** Sentry options that can be used to configure the SDK. */
public open class SentryOptions {
Expand Down Expand Up @@ -120,4 +122,53 @@ public open class SentryOptions {
* transactions will be sent. Transactions are picked randomly. Default is null (disabled)
*/
public var tracesSampleRate: Double? = null

/**
* Controls the tracking of App Hangs capturing moments when the application
* becomes unresponsive for a set duration.
*
* **Default**: Enabled.
*
* **Platform Availability**: Cocoa.
*
* For more information, refer to the Cocoa documentation on App Hangs:
* [Cocoa App Hangs](https://docs.sentry.io/platforms/apple/configuration/app-hangs/)
*/
public var enableAppHangTracking: Boolean = true

/**
* Defines the timeout interval in milliseconds for detecting App Hangs.
*
* **Default**: 2000 milliseconds (2 seconds).
*
* **Platform Availability**: Cocoa.
*
* For configuration details and best practices, see:
* [Cocoa App Hangs](https://docs.sentry.io/platforms/apple/configuration/app-hangs/)
*/
public var appHangTimeoutIntervalMillis: Long = DEFAULT_APPHANG_TIMEOUT_INTERVAL_MILLIS

/**
* Enables or disables ANR (Application Not Responding) tracking.
*
* **Default**: Enabled.
*
* **Platform Availability**: Android.
*
* Detailed documentation on ANR tracking can be found here:
* [Android ANR](https://docs.sentry.io/platforms/android/configuration/app-not-respond/)
*/
public var isAnrEnabled: Boolean = true

/**
* Sets the timeout interval in milliseconds for considering an application as not responding (ANR).
*
* **Default**: 5000 milliseconds (5 seconds).
*
* **Platform Availability**: Android.
*
* For more information on configuring ANR detection, visit:
* [Android ANR](https://docs.sentry.io/platforms/android/configuration/app-not-respond/)
*/
public var anrTimeoutIntervalMillis: Long = DEFAULT_ANR_TIMEOUT_INTERVAL_MILLIS
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package io.sentry.kotlin.multiplatform

interface CommonPlatformOptions {
val dsn: String?
val attachStackTrace: Boolean
val release: String?
val debug: Boolean
val environment: String?
val dist: String?
val enableAutoSessionTracking: Boolean
val sessionTrackingIntervalMillis: Long
val maxBreadcrumbs: Int
val maxAttachmentSize: Long
val sampleRate: Double?
val tracesSampleRate: Double?

fun applyFromOptions(options: SentryOptions)
}

expect interface PlatformOptions : CommonPlatformOptions

expect fun createPlatformOptions(): PlatformOptions
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import io.sentry.kotlin.multiplatform.protocol.Breadcrumb
import io.sentry.kotlin.multiplatform.utils.fakeDsn
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertNull
import kotlin.test.assertTrue

class SentryOptionsTest : BaseSentryTest() {
@Test
Expand Down Expand Up @@ -93,4 +96,79 @@ class SentryOptionsTest : BaseSentryTest() {

assertEquals(null, modifiedBreadcrumb)
}

@Test
fun `GIVEN SentryOptions THEN default values are set`() {
val options = SentryOptions()

assertNull(options.dsn)
assertTrue(options.attachStackTrace)
assertTrue(options.attachThreads)
assertNull(options.release)
assertFalse(options.debug)
assertNull(options.environment)
assertNull(options.dist)
assertTrue(options.enableAutoSessionTracking)
assertEquals(DEFAULT_SESSION_INTERVAL_MILLIS, options.sessionTrackingIntervalMillis)
assertFalse(options.attachScreenshot)
assertNull(options.beforeBreadcrumb)
assertNull(options.beforeSend)
assertNull(options.sdk)
assertEquals(DEFAULT_MAX_BREADCRUMBS, options.maxBreadcrumbs)
assertEquals(DEFAULT_MAX_ATTACHMENT_SIZE, options.maxAttachmentSize)
assertFalse(options.attachViewHierarchy)
assertTrue(options.enableCaptureFailedRequests)
assertEquals(listOf(HttpStatusCodeRange()), options.failedRequestStatusCodes)
assertEquals(listOf(".*"), options.failedRequestTargets)
assertNull(options.sampleRate)
assertNull(options.tracesSampleRate)
assertTrue(options.enableAppHangTracking)
assertEquals(2000L, options.appHangTimeoutIntervalMillis)
assertTrue(options.isAnrEnabled)
assertEquals(5000L, options.anrTimeoutIntervalMillis)
}

@Test
fun `GIVEN SentryOptions WHEN applyFromOptions THEN applies values to native options`() {
val options = SentryOptions().apply {
dsn = fakeDsn
attachStackTrace = false
release = "release"
debug = true
environment = "environment"
dist = "dist"
enableAutoSessionTracking = false
sessionTrackingIntervalMillis = 1000L
maxBreadcrumbs = 10
maxAttachmentSize = 100L
sampleRate = 0.5
tracesSampleRate = 0.5
attachScreenshot = true
attachViewHierarchy = true
enableAppHangTracking = false
appHangTimeoutIntervalMillis = 1000L
isAnrEnabled = false
anrTimeoutIntervalMillis = 1000L
}

val platformOptions = createPlatformOptions()
platformOptions.applyFromOptions(options)

assertEquals(fakeDsn, platformOptions.dsn)
assertFalse(platformOptions.attachStackTrace)
assertEquals("release", platformOptions.release)
assertTrue(platformOptions.debug)
assertEquals("environment", platformOptions.environment)
assertEquals("dist", platformOptions.dist)
assertFalse(platformOptions.enableAutoSessionTracking)
assertEquals(1000L, platformOptions.sessionTrackingIntervalMillis)
assertEquals(10, platformOptions.maxBreadcrumbs)
assertEquals(100L, platformOptions.maxAttachmentSize)
assertEquals(0.5, platformOptions.sampleRate)
assertEquals(0.5, platformOptions.tracesSampleRate)

platformOptions.assertPlatformSpecificOptions(options)
}
}

expect fun PlatformOptions.assertPlatformSpecificOptions(options: SentryOptions)
Loading