From 44904094884a9c5d73d8473f4204498eeed04e61 Mon Sep 17 00:00:00 2001 From: buenaflor Date: Fri, 28 Apr 2023 01:39:53 +0200 Subject: [PATCH 01/43] add basic instrumentation setup --- .../extensions/SentryOptionsExtensions.kt | 3 + .../extensions/SentryOptionsExtensions.kt | 1 + .../kotlin/multiplatform/Instrumenter.kt | 12 ++ .../sentry/kotlin/multiplatform/SentryDate.kt | 39 +++++++ .../kotlin/multiplatform/SentryOptions.kt | 8 ++ .../io/sentry/kotlin/multiplatform/Span.kt | 88 ++++++++++++++ .../sentry/kotlin/multiplatform/SpanStatus.kt | 109 ++++++++++++++++++ .../kotlin/multiplatform/Transaction.kt | 5 + 8 files changed, 265 insertions(+) create mode 100644 sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Instrumenter.kt create mode 100644 sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryDate.kt create mode 100644 sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Span.kt create mode 100644 sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SpanStatus.kt create mode 100644 sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Transaction.kt diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.kt index 973de837..3a236855 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.kt @@ -8,7 +8,9 @@ import io.sentry.kotlin.multiplatform.CocoaSentryOptions import io.sentry.kotlin.multiplatform.SentryEvent import io.sentry.kotlin.multiplatform.SentryOptions import io.sentry.kotlin.multiplatform.nsexception.dropKotlinCrashEvent +import kotlinx.cinterop.UnsafeNumber import kotlinx.cinterop.convert +import platform.Foundation.NSNumber import NSException.Sentry.SentryEvent as NSExceptionSentryEvent internal fun SentryOptions.toCocoaOptionsConfiguration(): (CocoaSentryOptions?) -> Unit = { @@ -23,6 +25,7 @@ internal fun CocoaSentryOptions.applyCocoaBaseOptions(options: SentryOptions) { dsn = options.dsn attachStacktrace = options.attachStackTrace dist = options.dist + tracesSampleRate = options.tracesSampleRate?.let { NSNumber(it) } options.environment?.let { environment = it } diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.kt index f793dda9..e1946d36 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.kt @@ -33,6 +33,7 @@ internal fun JvmSentryOptions.applyJvmBaseOptions(options: SentryOptions) { isAttachThreads = options.attachThreads isAttachStacktrace = options.attachStackTrace dist = options.dist + tracesSampleRate = options.tracesSampleRate environment = options.environment release = options.release isDebug = options.debug diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Instrumenter.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Instrumenter.kt new file mode 100644 index 00000000..d6c0952e --- /dev/null +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Instrumenter.kt @@ -0,0 +1,12 @@ +package io.sentry.kotlin.multiplatform + +/** + * Which framework is responsible for instrumenting. This includes starting and stopping of + * transactions and spans. + */ +public enum class Instrumenter { + SENTRY, + + /** OpenTelemetry */ + OTEL +} \ No newline at end of file diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryDate.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryDate.kt new file mode 100644 index 00000000..3434a9ae --- /dev/null +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryDate.kt @@ -0,0 +1,39 @@ +package io.sentry.kotlin.multiplatform + +public abstract class SentryDate : Comparable { + /** Returns the date in nanoseconds as long. */ + public abstract fun nanoTimestamp(): Long + + /** + * Calculates a date by using another date. + * + * + * This is a workaround for limited precision offered in some cases (e.g. when using [ ]). This makes it possible to have high precision duration by using + * nanoseconds for the finish timestamp where normally the start and finish timestamps would only + * offer millisecond precision. + * + * @param otherDate another [SentryDate] + * @return date in seconds as long + */ + public fun laterDateNanosTimestampByDiff(otherDate: SentryDate?): Long { + return if (otherDate != null && compareTo(otherDate) < 0) { + otherDate.nanoTimestamp() + } else { + nanoTimestamp() + } + } + + /** + * Difference between two dates in nanoseconds. + * + * @param otherDate another [SentryDate] + * @return difference in nanoseconds + */ + public fun diff(otherDate: SentryDate): Long { + return nanoTimestamp() - otherDate.nanoTimestamp() + } + + public override fun compareTo(other: SentryDate?): Int { + return nanoTimestamp().compareTo(other?.nanoTimestamp() ?: 0) + } +} 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 547f45a7..452266f2 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 @@ -40,6 +40,14 @@ public open class SentryOptions { /** Sets the distribution. Think about it together with release and environment */ public var dist: String? = null + /** + * Configures the sample rate as a percentage of transactions to be sent in the range of 0.0 to 1.0. + * If set to 1.0 then 100% of transactions are sent. + * If set to 0.1 only 10% of transactions are sent. + * Transactions are picked randomly. Default is null (disabled) + */ + public var tracesSampleRate: Double? = null + /** Whether to enable or disable automatic session tracking. */ public var enableAutoSessionTracking: Boolean = true diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Span.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Span.kt new file mode 100644 index 00000000..69d4c50f --- /dev/null +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Span.kt @@ -0,0 +1,88 @@ +package io.sentry.kotlin.multiplatform + +public interface Span { + /** + * Starts a child Span. + * + * @param operation - new span operation name + * @return a new transaction span + */ + public fun startChild(operation: String): Span + + public fun startChild( + operation: String, + description: String?, + timestamp: SentryDate, + instrumenter: Instrumenter + ): Span + + /** + * Starts a child Span. + * + * @param operation - new span operation name + * @param description - new span description name + * @return a new transaction span + */ + public fun startChild(operation: String, description: String?): Span + + /** Sets span timestamp marking this span as finished. */ + public fun finish() + + /** + * Sets span timestamp marking this span as finished. + * + * @param status - the status + */ + public fun finish(status: SpanStatus) + + /** + * Sets span timestamp marking this span as finished. + * + * @param status - the status + * @param timestamp - the end timestamp + */ + public fun finish(status: SpanStatus?, timestamp: SentryDate) + + /** The span operation. */ + public var operation: String + + /** The span description. */ + public var description: String? + + /** The span status. */ + public var status: SpanStatus + + /** The throwable that was thrown during the execution of the span. */ + public var throwable: Throwable? + + /** + * Sets the tag on span or transaction. + * + * @param key the tag key + * @param value the tag value + */ + public fun setTag(key: String, value: String) + public fun getTag(key: String): String? + + /** + * Returns if span has finished. + * + * @return if span has finished. + */ + public val isFinished: Boolean + + /** + * Sets extra data on span or transaction. + * + * @param key the data key + * @param value the data value + */ + public fun setData(key: String, value: Any) + + /** + * Returns extra data from span or transaction. + * + * @return the data + */ + public fun getData(key: String): Any? +} \ No newline at end of file diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SpanStatus.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SpanStatus.kt new file mode 100644 index 00000000..2f0dc28f --- /dev/null +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SpanStatus.kt @@ -0,0 +1,109 @@ +package io.sentry.kotlin.multiplatform + +public enum class SpanStatus { + /** Not an error, returned on success. */ + OK(200, 299), + + /** The operation was cancelled, typically by the caller. */ + CANCELLED(499), + + /** + * Some invariants expected by the underlying system have been broken. This code is reserved for + * serious errors. + */ + INTERNAL_ERROR(500), + + /** An unknown error raised by APIs that don't return enough error information. */ + UNKNOWN(500), + + /** An unknown error raised by APIs that don't return enough error information. */ + UNKNOWN_ERROR(500), + + /** The client specified an invalid argument. */ + INVALID_ARGUMENT(400), + + /** The deadline expired before the operation could succeed. */ + DEADLINE_EXCEEDED(504), + + /** Content was not found or request was denied for an entire class of users. */ + NOT_FOUND(404), + + /** The entity attempted to be created already exists */ + ALREADY_EXISTS(409), + + /** The caller doesn't have permission to execute the specified operation. */ + PERMISSION_DENIED(403), + + /** The resource has been exhausted e.g. per-user quota exhausted, file system out of space. */ + RESOURCE_EXHAUSTED(429), + + /** The client shouldn't retry until the system state has been explicitly handled. */ + FAILED_PRECONDITION(400), + + /** The operation was aborted. */ + ABORTED(409), + + /** The operation was attempted past the valid range e.g. seeking past the end of a file. */ + OUT_OF_RANGE(400), + + /** The operation is not implemented or is not supported/enabled for this operation. */ + UNIMPLEMENTED(501), + + /** The service is currently available e.g. as a transient condition. */ + UNAVAILABLE(503), + + /** Unrecoverable data loss or corruption. */ + DATA_LOSS(500), + + /** The requester doesn't have valid authentication credentials for the operation. */ + UNAUTHENTICATED(401); + + private val minHttpStatusCode: Int + private val maxHttpStatusCode: Int + + constructor(httpStatusCode: Int) { + minHttpStatusCode = httpStatusCode + maxHttpStatusCode = httpStatusCode + } + + constructor(minHttpStatusCode: Int, maxHttpStatusCode: Int) { + this.minHttpStatusCode = minHttpStatusCode + this.maxHttpStatusCode = maxHttpStatusCode + } + + private fun matches(httpStatusCode: Int): Boolean { + return httpStatusCode in minHttpStatusCode..maxHttpStatusCode + } + + public companion object { + /** + * Creates [SpanStatus] from HTTP status code. + * + * @param httpStatusCode the http status code + * @return span status equivalent of http status code or null if not found + */ + public fun fromHttpStatusCode(httpStatusCode: Int): SpanStatus? { + for (status in SpanStatus.values()) { + if (status.matches(httpStatusCode)) { + return status + } + } + return null + } + + /** + * Creates [SpanStatus] from HTTP status code. + * + * @param httpStatusCode the http status code + * @param defaultStatus the default SpanStatus + * @return span status equivalent of http status code or defaultStatus if not found + */ + public fun fromHttpStatusCode( + httpStatusCode: Int?, defaultStatus: SpanStatus + ): SpanStatus { + val spanStatus = + if (httpStatusCode != null) fromHttpStatusCode(httpStatusCode) else defaultStatus + return spanStatus ?: defaultStatus + } + } +} \ No newline at end of file diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Transaction.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Transaction.kt new file mode 100644 index 00000000..9f26f66e --- /dev/null +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Transaction.kt @@ -0,0 +1,5 @@ +package io.sentry.kotlin.multiplatform + +public interface Transaction { + +} \ No newline at end of file From 34c70d85d0a798c386278378eecae1530395db9a Mon Sep 17 00:00:00 2001 From: buenaflor Date: Fri, 28 Apr 2023 01:40:20 +0200 Subject: [PATCH 02/43] format --- .../multiplatform/extensions/SentryOptionsExtensions.kt | 1 - .../kotlin/io/sentry/kotlin/multiplatform/Instrumenter.kt | 2 +- .../commonMain/kotlin/io/sentry/kotlin/multiplatform/Span.kt | 2 +- .../kotlin/io/sentry/kotlin/multiplatform/SpanStatus.kt | 5 +++-- .../kotlin/io/sentry/kotlin/multiplatform/Transaction.kt | 4 +--- 5 files changed, 6 insertions(+), 8 deletions(-) diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.kt index 3a236855..4e30267f 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.kt @@ -8,7 +8,6 @@ import io.sentry.kotlin.multiplatform.CocoaSentryOptions import io.sentry.kotlin.multiplatform.SentryEvent import io.sentry.kotlin.multiplatform.SentryOptions import io.sentry.kotlin.multiplatform.nsexception.dropKotlinCrashEvent -import kotlinx.cinterop.UnsafeNumber import kotlinx.cinterop.convert import platform.Foundation.NSNumber import NSException.Sentry.SentryEvent as NSExceptionSentryEvent diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Instrumenter.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Instrumenter.kt index d6c0952e..80910c7c 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Instrumenter.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Instrumenter.kt @@ -9,4 +9,4 @@ public enum class Instrumenter { /** OpenTelemetry */ OTEL -} \ No newline at end of file +} diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Span.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Span.kt index 69d4c50f..7113c086 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Span.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Span.kt @@ -85,4 +85,4 @@ public interface Span { * @return the data */ public fun getData(key: String): Any? -} \ No newline at end of file +} diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SpanStatus.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SpanStatus.kt index 2f0dc28f..1658fa09 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SpanStatus.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SpanStatus.kt @@ -99,11 +99,12 @@ public enum class SpanStatus { * @return span status equivalent of http status code or defaultStatus if not found */ public fun fromHttpStatusCode( - httpStatusCode: Int?, defaultStatus: SpanStatus + httpStatusCode: Int?, + defaultStatus: SpanStatus ): SpanStatus { val spanStatus = if (httpStatusCode != null) fromHttpStatusCode(httpStatusCode) else defaultStatus return spanStatus ?: defaultStatus } } -} \ No newline at end of file +} diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Transaction.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Transaction.kt index 9f26f66e..2cd51355 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Transaction.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Transaction.kt @@ -1,5 +1,3 @@ package io.sentry.kotlin.multiplatform -public interface Transaction { - -} \ No newline at end of file +public interface Transaction From 265ebef29275fafbf9381f6758d9ed53e50039d1 Mon Sep 17 00:00:00 2001 From: buenaflor Date: Fri, 28 Apr 2023 04:39:19 +0200 Subject: [PATCH 03/43] add transaction wrappers --- .../sentry/kotlin/multiplatform/SentryInit.kt | 1 + .../kotlin/multiplatform/SentryBridge.kt | 5 ++++ .../multiplatform/TransactionWrapper.kt | 10 +++++++ .../kotlin/multiplatform/SentryBridge.kt | 5 ++++ .../multiplatform/TransactionWrapper.kt | 6 ++++ .../kotlin/multiplatform/SentryBridge.kt | 2 ++ .../sentry/kotlin/multiplatform/SentryKMP.kt | 4 +++ .../kotlin/multiplatform/Transaction.kt | 28 ++++++++++++++++++- .../multiplatform/TransactionWrapper.kt | 5 ++++ 9 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/TransactionWrapper.kt create mode 100644 sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/TransactionWrapper.kt create mode 100644 sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/TransactionWrapper.kt diff --git a/sentry-kotlin-multiplatform/src/androidMain/kotlin/io/sentry/kotlin/multiplatform/SentryInit.kt b/sentry-kotlin-multiplatform/src/androidMain/kotlin/io/sentry/kotlin/multiplatform/SentryInit.kt index 8777b6eb..176f1fbc 100644 --- a/sentry-kotlin-multiplatform/src/androidMain/kotlin/io/sentry/kotlin/multiplatform/SentryInit.kt +++ b/sentry-kotlin-multiplatform/src/androidMain/kotlin/io/sentry/kotlin/multiplatform/SentryInit.kt @@ -10,6 +10,7 @@ internal actual fun initSentry(context: Context?, configuration: OptionsConfigur context?.let { SentryAndroid.init(it, options.toAndroidSentryOptionsCallback()) } + io.sentry.Sentry.startTransaction(", ", "") } public actual typealias Context = Context diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt index 9c6d0cf8..fe1b30e2 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt @@ -62,6 +62,11 @@ internal actual object SentryBridge { SentrySDK.setUser(user?.toCocoaUser()) } + actual fun startTransaction(operation: String, description: String): Transaction { + val cocoaTransaction = SentrySDK.startTransactionWithName(operation, description) + return + } + actual fun close() { SentrySDK.close() } diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/TransactionWrapper.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/TransactionWrapper.kt new file mode 100644 index 00000000..6c8f834c --- /dev/null +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/TransactionWrapper.kt @@ -0,0 +1,10 @@ +package io.sentry.kotlin.multiplatform + +import cocoapods.Sentry.SentrySpanProtocol + +public actual abstract class TransactionWrapper(private val cocoaTransaction: SentrySpanProtocol) : + Transaction { + override fun startChild(operation: String): Span { + cocoaTransaction.startChildWithOperation(operation) + } +} \ No newline at end of file diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt index 15913c06..62b9061f 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt @@ -57,6 +57,11 @@ internal actual object SentryBridge { Sentry.setUser(user?.toJvmUser()) } + actual fun startTransaction(operation: String, description: String): Transaction { + val jvmTransaction = Sentry.startTransaction(operation, description) + return Transaction(jvmTransaction) + } + actual fun close() { Sentry.close() } diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/TransactionWrapper.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/TransactionWrapper.kt new file mode 100644 index 00000000..7f1a0bff --- /dev/null +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/TransactionWrapper.kt @@ -0,0 +1,6 @@ +package io.sentry.kotlin.multiplatform + +import io.sentry.ITransaction + +public actual abstract class TransactionWrapper(jvmTransaction: ITransaction) : Transaction { +} \ No newline at end of file diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt index 32c6a074..257dec9c 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt @@ -27,5 +27,7 @@ internal expect object SentryBridge { fun setUser(user: User?) + fun startTransaction(operation: String, description: String): Transaction + fun close() } diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryKMP.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryKMP.kt index 3f7cbc08..2e55072d 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryKMP.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryKMP.kt @@ -111,6 +111,10 @@ public object Sentry { SentryBridge.setUser(user) } + public fun startTransaction(name: String, operation: String): Transaction { + return SentryBridge.startTransaction(name, operation) + } + /** * Throws a RuntimeException, useful for testing. */ diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Transaction.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Transaction.kt index 2cd51355..203e4b8a 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Transaction.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Transaction.kt @@ -1,3 +1,29 @@ package io.sentry.kotlin.multiplatform -public interface Transaction +import io.sentry.kotlin.multiplatform.protocol.SentryId + +public interface Transaction : Span { + /** The transaction name. */ + public var name: String + + /** + * Returns if transaction is sampled. + * + * @return is sampled + */ + public fun isSampled(): Boolean? + + /** + * Returns the latest span that is not finished. + * + * @return span or null if not found. + */ + public fun getLatestActiveSpan(): Span + + /** + * Returns transaction's event id. + * + * @return the event id + */ + public fun getEventId(): SentryId +} diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/TransactionWrapper.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/TransactionWrapper.kt new file mode 100644 index 00000000..9b19ec75 --- /dev/null +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/TransactionWrapper.kt @@ -0,0 +1,5 @@ +package io.sentry.kotlin.multiplatform + +public expect abstract class TransactionWrapper : Transaction { + +} \ No newline at end of file From ad838eeb2dc28ad90974e8f5b04ead450f832f88 Mon Sep 17 00:00:00 2001 From: buenaflor Date: Fri, 28 Apr 2023 12:51:03 +0200 Subject: [PATCH 04/43] add span provider --- .../kotlin/multiplatform/CocoaSpanProvider.kt | 61 +++++++++++++++++++ .../kotlin/multiplatform/SentryBridge.kt | 4 +- .../multiplatform/TransactionWrapper.kt | 10 --- .../kotlin/multiplatform/TypeAliases.kt | 2 + .../extensions/SpanStatusExtensions.kt | 49 +++++++++++++++ .../kotlin/multiplatform/JvmSpanProvider.kt | 59 ++++++++++++++++++ .../kotlin/multiplatform/SentryBridge.kt | 6 +- .../multiplatform/TransactionWrapper.kt | 6 -- .../kotlin/multiplatform/TypeAliases.kt | 3 + .../extensions/SpanStatusExtensions.kt | 50 +++++++++++++++ .../io/sentry/kotlin/multiplatform/Span.kt | 20 +----- .../kotlin/multiplatform/SpanWrapper.kt | 3 + .../multiplatform/TransactionWrapper.kt | 5 -- 13 files changed, 234 insertions(+), 44 deletions(-) create mode 100644 sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/CocoaSpanProvider.kt delete mode 100644 sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/TransactionWrapper.kt create mode 100644 sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SpanStatusExtensions.kt create mode 100644 sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/JvmSpanProvider.kt delete mode 100644 sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/TransactionWrapper.kt create mode 100644 sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SpanStatusExtensions.kt create mode 100644 sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SpanWrapper.kt delete mode 100644 sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/TransactionWrapper.kt diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/CocoaSpanProvider.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/CocoaSpanProvider.kt new file mode 100644 index 00000000..7c32cf00 --- /dev/null +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/CocoaSpanProvider.kt @@ -0,0 +1,61 @@ +package io.sentry.kotlin.multiplatform + +import cocoapods.Sentry.SentrySpanProtocol +import io.sentry.kotlin.multiplatform.extensions.toCocoa +import io.sentry.kotlin.multiplatform.extensions.toKmp + +internal class CocoaSpanProvider(private val cocoaSpan: SentrySpanProtocol) : Span { + override fun startChild(operation: String): Span { + val cocoaSpan = cocoaSpan.startChildWithOperation(operation) + return CocoaSpanProvider(cocoaSpan) + } + + override fun startChild(operation: String, description: String?): Span { + val cocoaSpan = cocoaSpan.startChildWithOperation(operation = operation, description = description) + return CocoaSpanProvider(cocoaSpan) + } + + override fun finish() { + cocoaSpan.finish() + } + + override fun finish(status: SpanStatus) { + cocoaSpan.finishWithStatus(status.toCocoa()) + } + + override var operation: String + get() = cocoaSpan.operation + set(value) { + cocoaSpan.operation = value + } + override var description: String? + get() = cocoaSpan.spanDescription + set(value) { + cocoaSpan.setSpanDescription(value) + } + override var status: SpanStatus? + get() = cocoaSpan.status.toKmp() + set(value) { + value?.let { + cocoaSpan.status = it.toCocoa() + } + } + override fun setTag(key: String, value: String) { + cocoaSpan.setTagValue(value = value, forKey = key) + } + + override fun getTag(key: String): String? { + return cocoaSpan.tags[key] as String? + } + + override val isFinished: Boolean + get() = cocoaSpan.isFinished + + override fun setData(key: String, value: Any) { + cocoaSpan.setDataValue(value = value, forKey = key) + } + + override fun getData(key: String): Any? { + return cocoaSpan.data[key] + } +} \ No newline at end of file diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt index fe1b30e2..11cbe56c 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt @@ -63,8 +63,8 @@ internal actual object SentryBridge { } actual fun startTransaction(operation: String, description: String): Transaction { - val cocoaTransaction = SentrySDK.startTransactionWithName(operation, description) - return + val span = SentrySDK.startTransactionWithName(operation, description) + TODO() } actual fun close() { diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/TransactionWrapper.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/TransactionWrapper.kt deleted file mode 100644 index 6c8f834c..00000000 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/TransactionWrapper.kt +++ /dev/null @@ -1,10 +0,0 @@ -package io.sentry.kotlin.multiplatform - -import cocoapods.Sentry.SentrySpanProtocol - -public actual abstract class TransactionWrapper(private val cocoaTransaction: SentrySpanProtocol) : - Transaction { - override fun startChild(operation: String): Span { - cocoaTransaction.startChildWithOperation(operation) - } -} \ No newline at end of file diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/TypeAliases.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/TypeAliases.kt index a85825f9..53fdec63 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/TypeAliases.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/TypeAliases.kt @@ -9,6 +9,7 @@ import cocoapods.Sentry.SentryLevel import cocoapods.Sentry.SentryMessage import cocoapods.Sentry.SentryOptions import cocoapods.Sentry.SentryScope +import cocoapods.Sentry.SentrySpanStatus import cocoapods.Sentry.SentryUser import cocoapods.Sentry.SentryUserFeedback @@ -23,3 +24,4 @@ internal typealias CocoaUserFeedback = SentryUserFeedback internal typealias CocoaSentryEvent = SentryEvent internal typealias CocoaMessage = SentryMessage internal typealias CocoaSentryException = SentryException +internal typealias CocoaSpanStatus = SentrySpanStatus \ No newline at end of file diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SpanStatusExtensions.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SpanStatusExtensions.kt new file mode 100644 index 00000000..dc4340bd --- /dev/null +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SpanStatusExtensions.kt @@ -0,0 +1,49 @@ +package io.sentry.kotlin.multiplatform.extensions + +import io.sentry.kotlin.multiplatform.CocoaSpanStatus +import io.sentry.kotlin.multiplatform.SpanStatus + +internal fun SpanStatus.toCocoa(): CocoaSpanStatus { + return when (this) { + SpanStatus.ABORTED -> CocoaSpanStatus.kSentrySpanStatusAborted + SpanStatus.ALREADY_EXISTS -> CocoaSpanStatus.kSentrySpanStatusAlreadyExists + SpanStatus.CANCELLED -> CocoaSpanStatus.kSentrySpanStatusCancelled + SpanStatus.DATA_LOSS -> CocoaSpanStatus.kSentrySpanStatusDataLoss + SpanStatus.DEADLINE_EXCEEDED -> CocoaSpanStatus.kSentrySpanStatusDeadlineExceeded + SpanStatus.FAILED_PRECONDITION -> CocoaSpanStatus.kSentrySpanStatusFailedPrecondition + SpanStatus.INVALID_ARGUMENT -> CocoaSpanStatus.kSentrySpanStatusInvalidArgument + SpanStatus.NOT_FOUND -> CocoaSpanStatus.kSentrySpanStatusNotFound + SpanStatus.OK -> CocoaSpanStatus.kSentrySpanStatusOk + SpanStatus.OUT_OF_RANGE -> CocoaSpanStatus.kSentrySpanStatusOutOfRange + SpanStatus.PERMISSION_DENIED -> CocoaSpanStatus.kSentrySpanStatusPermissionDenied + SpanStatus.RESOURCE_EXHAUSTED -> CocoaSpanStatus.kSentrySpanStatusResourceExhausted + SpanStatus.UNAUTHENTICATED -> CocoaSpanStatus.kSentrySpanStatusUnauthenticated + SpanStatus.UNAVAILABLE -> CocoaSpanStatus.kSentrySpanStatusUnavailable + SpanStatus.UNIMPLEMENTED -> CocoaSpanStatus.kSentrySpanStatusUnimplemented + else -> { + CocoaSpanStatus.kSentrySpanStatusUnknownError + } + } +} + +internal fun CocoaSpanStatus.toKmp(): SpanStatus { + return when (this) { + CocoaSpanStatus.kSentrySpanStatusAborted -> SpanStatus.ABORTED + CocoaSpanStatus.kSentrySpanStatusAlreadyExists -> SpanStatus.ALREADY_EXISTS + CocoaSpanStatus.kSentrySpanStatusCancelled -> SpanStatus.CANCELLED + CocoaSpanStatus.kSentrySpanStatusDataLoss -> SpanStatus.DATA_LOSS + CocoaSpanStatus.kSentrySpanStatusDeadlineExceeded -> SpanStatus.DEADLINE_EXCEEDED + CocoaSpanStatus.kSentrySpanStatusFailedPrecondition -> SpanStatus.FAILED_PRECONDITION + CocoaSpanStatus.kSentrySpanStatusInvalidArgument -> SpanStatus.INVALID_ARGUMENT + CocoaSpanStatus.kSentrySpanStatusNotFound -> SpanStatus.NOT_FOUND + CocoaSpanStatus.kSentrySpanStatusOk -> SpanStatus.OK + CocoaSpanStatus.kSentrySpanStatusOutOfRange -> SpanStatus.OUT_OF_RANGE + CocoaSpanStatus.kSentrySpanStatusPermissionDenied -> SpanStatus.PERMISSION_DENIED + CocoaSpanStatus.kSentrySpanStatusResourceExhausted -> SpanStatus.RESOURCE_EXHAUSTED + CocoaSpanStatus.kSentrySpanStatusUnauthenticated -> SpanStatus.UNAUTHENTICATED + CocoaSpanStatus.kSentrySpanStatusUnavailable -> SpanStatus.UNAVAILABLE + CocoaSpanStatus.kSentrySpanStatusUnimplemented -> SpanStatus.UNIMPLEMENTED + else -> SpanStatus.UNKNOWN + } +} + diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/JvmSpanProvider.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/JvmSpanProvider.kt new file mode 100644 index 00000000..381c5083 --- /dev/null +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/JvmSpanProvider.kt @@ -0,0 +1,59 @@ +package io.sentry.kotlin.multiplatform + +import io.sentry.ISpan +import io.sentry.kotlin.multiplatform.extensions.toJvm +import io.sentry.kotlin.multiplatform.extensions.toKmp + +internal class JvmSpanProvider(private val jvmSpan: ISpan) : Span { + override fun startChild(operation: String): Span { + val jvmSpan = jvmSpan.startChild(operation) + return JvmSpanProvider(jvmSpan) + } + + override fun startChild(operation: String, description: String?): Span { + val jvmSpan = jvmSpan.startChild(operation, description) + return JvmSpanProvider(jvmSpan) + } + + override fun finish() { + jvmSpan.finish() + } + + override fun finish(status: SpanStatus) { + jvmSpan.finish(status.toJvm()) + } + + override var operation: String + get() = jvmSpan.operation + set(value) { + jvmSpan.operation = value + } + override var description: String? + get() = jvmSpan.description + set(value) { + jvmSpan.description = value + } + override var status: SpanStatus? + get() = jvmSpan.status?.toKmp() + set(value) { + jvmSpan.status = value?.toJvm() + } + override fun setTag(key: String, value: String) { + jvmSpan.setTag(key, value) + } + + override fun getTag(key: String): String? { + return jvmSpan.getTag(key) + } + + override val isFinished: Boolean + get() = jvmSpan.isFinished + + override fun setData(key: String, value: Any) { + jvmSpan.setData(key, value) + } + + override fun getData(key: String): Any? { + return jvmSpan.getData(key) + } +} \ No newline at end of file diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt index 62b9061f..776f1ead 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt @@ -1,6 +1,9 @@ package io.sentry.kotlin.multiplatform import io.sentry.Sentry +import io.sentry.SentryDateProvider +import io.sentry.SentryInstantDate +import io.sentry.SentryLongDate import io.sentry.kotlin.multiplatform.extensions.toJvmBreadcrumb import io.sentry.kotlin.multiplatform.extensions.toJvmUser import io.sentry.kotlin.multiplatform.extensions.toJvmUserFeedback @@ -58,8 +61,7 @@ internal actual object SentryBridge { } actual fun startTransaction(operation: String, description: String): Transaction { - val jvmTransaction = Sentry.startTransaction(operation, description) - return Transaction(jvmTransaction) + TODO("Not yet implemented") } actual fun close() { diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/TransactionWrapper.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/TransactionWrapper.kt deleted file mode 100644 index 7f1a0bff..00000000 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/TransactionWrapper.kt +++ /dev/null @@ -1,6 +0,0 @@ -package io.sentry.kotlin.multiplatform - -import io.sentry.ITransaction - -public actual abstract class TransactionWrapper(jvmTransaction: ITransaction) : Transaction { -} \ No newline at end of file diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/TypeAliases.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/TypeAliases.kt index 68164e6e..35fb24cd 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/TypeAliases.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/TypeAliases.kt @@ -2,6 +2,7 @@ package io.sentry.kotlin.multiplatform import io.sentry.Attachment import io.sentry.Breadcrumb +import io.sentry.Instrumenter import io.sentry.Scope import io.sentry.SentryEvent import io.sentry.SentryLevel @@ -12,6 +13,7 @@ import io.sentry.protocol.Message import io.sentry.protocol.SentryException import io.sentry.protocol.SentryId import io.sentry.protocol.User +import io.sentry.SpanStatus internal typealias JvmSentryLevel = SentryLevel internal typealias JvmUser = User @@ -25,3 +27,4 @@ internal typealias JvmSentryEvent = SentryEvent internal typealias JvmMessage = Message internal typealias JvmSentryException = SentryException internal typealias JvmContexts = Contexts +internal typealias JvmSpanStatus = SpanStatus \ No newline at end of file diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SpanStatusExtensions.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SpanStatusExtensions.kt new file mode 100644 index 00000000..48b9f257 --- /dev/null +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SpanStatusExtensions.kt @@ -0,0 +1,50 @@ +package io.sentry.kotlin.multiplatform.extensions + +import io.sentry.kotlin.multiplatform.JvmSpanStatus +import io.sentry.kotlin.multiplatform.SpanStatus + +internal fun SpanStatus.toJvm(): JvmSpanStatus { + return when (this) { + SpanStatus.ABORTED -> JvmSpanStatus.ABORTED + SpanStatus.ALREADY_EXISTS -> JvmSpanStatus.ALREADY_EXISTS + SpanStatus.CANCELLED -> JvmSpanStatus.CANCELLED + SpanStatus.DATA_LOSS -> JvmSpanStatus.DATA_LOSS + SpanStatus.DEADLINE_EXCEEDED -> JvmSpanStatus.DEADLINE_EXCEEDED + SpanStatus.FAILED_PRECONDITION -> JvmSpanStatus.FAILED_PRECONDITION + SpanStatus.INVALID_ARGUMENT -> JvmSpanStatus.INVALID_ARGUMENT + SpanStatus.NOT_FOUND -> JvmSpanStatus.NOT_FOUND + SpanStatus.OK -> JvmSpanStatus.OK + SpanStatus.OUT_OF_RANGE -> JvmSpanStatus.OUT_OF_RANGE + SpanStatus.PERMISSION_DENIED -> JvmSpanStatus.PERMISSION_DENIED + SpanStatus.RESOURCE_EXHAUSTED -> JvmSpanStatus.RESOURCE_EXHAUSTED + SpanStatus.UNAUTHENTICATED -> JvmSpanStatus.UNAUTHENTICATED + SpanStatus.UNAVAILABLE -> JvmSpanStatus.UNAVAILABLE + SpanStatus.UNIMPLEMENTED -> JvmSpanStatus.UNIMPLEMENTED + else -> { + JvmSpanStatus.UNKNOWN + } + } +} + +internal fun JvmSpanStatus.toKmp(): SpanStatus { + return when (this) { + JvmSpanStatus.ABORTED -> SpanStatus.ABORTED + JvmSpanStatus.ALREADY_EXISTS -> SpanStatus.ALREADY_EXISTS + JvmSpanStatus.CANCELLED -> SpanStatus.CANCELLED + JvmSpanStatus.DATA_LOSS -> SpanStatus.DATA_LOSS + JvmSpanStatus.DEADLINE_EXCEEDED -> SpanStatus.DEADLINE_EXCEEDED + JvmSpanStatus.FAILED_PRECONDITION -> SpanStatus.FAILED_PRECONDITION + JvmSpanStatus.INVALID_ARGUMENT -> SpanStatus.INVALID_ARGUMENT + JvmSpanStatus.NOT_FOUND -> SpanStatus.NOT_FOUND + JvmSpanStatus.OK -> SpanStatus.OK + JvmSpanStatus.OUT_OF_RANGE -> SpanStatus.OUT_OF_RANGE + JvmSpanStatus.PERMISSION_DENIED -> SpanStatus.PERMISSION_DENIED + JvmSpanStatus.RESOURCE_EXHAUSTED -> SpanStatus.RESOURCE_EXHAUSTED + JvmSpanStatus.UNAUTHENTICATED -> SpanStatus.UNAUTHENTICATED + JvmSpanStatus.UNAVAILABLE -> SpanStatus.UNAVAILABLE + JvmSpanStatus.UNIMPLEMENTED -> SpanStatus.UNIMPLEMENTED + else -> { + SpanStatus.UNKNOWN + } + } +} \ No newline at end of file diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Span.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Span.kt index 7113c086..78c218b5 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Span.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Span.kt @@ -9,13 +9,6 @@ public interface Span { */ public fun startChild(operation: String): Span - public fun startChild( - operation: String, - description: String?, - timestamp: SentryDate, - instrumenter: Instrumenter - ): Span - /** * Starts a child Span. * @@ -35,14 +28,6 @@ public interface Span { */ public fun finish(status: SpanStatus) - /** - * Sets span timestamp marking this span as finished. - * - * @param status - the status - * @param timestamp - the end timestamp - */ - public fun finish(status: SpanStatus?, timestamp: SentryDate) - /** The span operation. */ public var operation: String @@ -50,10 +35,7 @@ public interface Span { public var description: String? /** The span status. */ - public var status: SpanStatus - - /** The throwable that was thrown during the execution of the span. */ - public var throwable: Throwable? + public var status: SpanStatus? /** * Sets the tag on span or transaction. diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SpanWrapper.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SpanWrapper.kt new file mode 100644 index 00000000..6e914120 --- /dev/null +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SpanWrapper.kt @@ -0,0 +1,3 @@ +package io.sentry.kotlin.multiplatform + +public class SpanWrapper(private val span: Span) : Span by span \ No newline at end of file diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/TransactionWrapper.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/TransactionWrapper.kt deleted file mode 100644 index 9b19ec75..00000000 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/TransactionWrapper.kt +++ /dev/null @@ -1,5 +0,0 @@ -package io.sentry.kotlin.multiplatform - -public expect abstract class TransactionWrapper : Transaction { - -} \ No newline at end of file From 02286be4cac5f4fb548f824dac7c4042c771445e Mon Sep 17 00:00:00 2001 From: buenaflor Date: Tue, 2 May 2023 09:37:09 +0200 Subject: [PATCH 05/43] improvement --- sentry-kotlin-multiplatform/build.gradle.kts | 1 + .../sentry/kotlin/multiplatform/SentryInit.kt | 1 - .../kotlin/multiplatform/SentryBridge.kt | 8 ++-- .../extensions/SentryOptionsExtensions.kt | 2 +- .../extensions/SpanStatusExtensions.kt | 2 +- .../kotlin/multiplatform/SentryBridge.kt | 8 +++- .../extensions/SentryOptionsExtensions.kt | 5 +- .../sentry/kotlin/multiplatform/Attachment.kt | 3 ++ .../kotlin/multiplatform/SentryBridge.kt | 2 +- .../sentry/kotlin/multiplatform/SentryKMP.kt | 46 ++++++++++++++++++- .../kotlin/multiplatform/SpanWrapper.kt | 3 -- .../sample/kmp/app/android/MainActivity.kt | 24 ++++++++++ .../kotlin/sample.kmp.app/AppSetup.kt | 14 ++++++ 13 files changed, 105 insertions(+), 14 deletions(-) delete mode 100644 sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SpanWrapper.kt diff --git a/sentry-kotlin-multiplatform/build.gradle.kts b/sentry-kotlin-multiplatform/build.gradle.kts index ea206854..279ed5bc 100644 --- a/sentry-kotlin-multiplatform/build.gradle.kts +++ b/sentry-kotlin-multiplatform/build.gradle.kts @@ -43,6 +43,7 @@ kotlin { val commonMain by getting { dependencies { implementation(Config.Libs.kotlinStd) + api("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.0-RC") } } val commonTest by getting { diff --git a/sentry-kotlin-multiplatform/src/androidMain/kotlin/io/sentry/kotlin/multiplatform/SentryInit.kt b/sentry-kotlin-multiplatform/src/androidMain/kotlin/io/sentry/kotlin/multiplatform/SentryInit.kt index 176f1fbc..8777b6eb 100644 --- a/sentry-kotlin-multiplatform/src/androidMain/kotlin/io/sentry/kotlin/multiplatform/SentryInit.kt +++ b/sentry-kotlin-multiplatform/src/androidMain/kotlin/io/sentry/kotlin/multiplatform/SentryInit.kt @@ -10,7 +10,6 @@ internal actual fun initSentry(context: Context?, configuration: OptionsConfigur context?.let { SentryAndroid.init(it, options.toAndroidSentryOptionsCallback()) } - io.sentry.Sentry.startTransaction(", ", "") } public actual typealias Context = Context diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt index 11cbe56c..a7f7d12c 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt @@ -1,6 +1,7 @@ package io.sentry.kotlin.multiplatform import cocoapods.Sentry.SentrySDK +import cocoapods.Sentry.SentrySpanProtocol import io.sentry.kotlin.multiplatform.extensions.toCocoaBreadcrumb import io.sentry.kotlin.multiplatform.extensions.toCocoaUser import io.sentry.kotlin.multiplatform.extensions.toCocoaUserFeedback @@ -62,9 +63,10 @@ internal actual object SentryBridge { SentrySDK.setUser(user?.toCocoaUser()) } - actual fun startTransaction(operation: String, description: String): Transaction { - val span = SentrySDK.startTransactionWithName(operation, description) - TODO() + actual fun startTransaction(operation: String, description: String): Span { + val cocoaSpan = SentrySDK.startTransactionWithName(operation, description) + + return CocoaSpanProvider(cocoaSpan) } actual fun close() { diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.kt index 4e30267f..beff66c9 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.kt @@ -52,7 +52,7 @@ internal fun CocoaSentryOptions.applyCocoaBaseOptions(options: SentryOptions) { sdk?.set("packages", packages) event?.sdk = sdk - + if (options.beforeSend == null) { dropKotlinCrashEvent(event as NSExceptionSentryEvent?) as CocoaSentryEvent? } else { diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SpanStatusExtensions.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SpanStatusExtensions.kt index dc4340bd..b6c3dba6 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SpanStatusExtensions.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SpanStatusExtensions.kt @@ -1,5 +1,6 @@ package io.sentry.kotlin.multiplatform.extensions +import cocoapods.Sentry.SentrySpanStatus import io.sentry.kotlin.multiplatform.CocoaSpanStatus import io.sentry.kotlin.multiplatform.SpanStatus @@ -46,4 +47,3 @@ internal fun CocoaSpanStatus.toKmp(): SpanStatus { else -> SpanStatus.UNKNOWN } } - diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt index 776f1ead..ccd81c9d 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt @@ -1,9 +1,12 @@ package io.sentry.kotlin.multiplatform +import io.sentry.ITransaction import io.sentry.Sentry import io.sentry.SentryDateProvider import io.sentry.SentryInstantDate import io.sentry.SentryLongDate +import io.sentry.SpanStatus +import io.sentry.TransactionContext import io.sentry.kotlin.multiplatform.extensions.toJvmBreadcrumb import io.sentry.kotlin.multiplatform.extensions.toJvmUser import io.sentry.kotlin.multiplatform.extensions.toJvmUserFeedback @@ -60,8 +63,9 @@ internal actual object SentryBridge { Sentry.setUser(user?.toJvmUser()) } - actual fun startTransaction(operation: String, description: String): Transaction { - TODO("Not yet implemented") + actual fun startTransaction(operation: String, description: String): Span { + val jvmTransaction = Sentry.startTransaction(operation, description) + return JvmSpanProvider(jvmTransaction) } actual fun close() { diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.kt index e1946d36..bb9bfa9a 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.kt @@ -24,6 +24,8 @@ internal fun SentryOptions.toJvmSentryOptionsCallback(): (JvmSentryOptions) -> U } } + + /** * Applies the given base SentryOptions to this JvmSentryOption * This avoids code duplication during init on Android @@ -45,6 +47,7 @@ internal fun JvmSentryOptions.applyJvmBaseOptions(options: SentryOptions) { options.beforeBreadcrumb?.invoke(jvmBreadcrumb.toKmpBreadcrumb())?.toJvmBreadcrumb() } setBeforeSend { jvmSentryEvent, hint -> + println("beforeSend: ${jvmSentryEvent.throwable}") if (options.beforeSend == null) { jvmSentryEvent } else { @@ -53,4 +56,4 @@ internal fun JvmSentryOptions.applyJvmBaseOptions(options: SentryOptions) { } } } -} +} \ No newline at end of file diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Attachment.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Attachment.kt index b72a9d63..b58bc908 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Attachment.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Attachment.kt @@ -31,3 +31,6 @@ public expect class Attachment { public constructor(pathname: String, filename: String, contentType: String?) } + + +public class MyHint : Exception() \ No newline at end of file diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt index 257dec9c..39cb5e01 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt @@ -27,7 +27,7 @@ internal expect object SentryBridge { fun setUser(user: User?) - fun startTransaction(operation: String, description: String): Transaction + fun startTransaction(operation: String, description: String): Span fun close() } diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryKMP.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryKMP.kt index 2e55072d..3d5769ad 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryKMP.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryKMP.kt @@ -4,6 +4,12 @@ import io.sentry.kotlin.multiplatform.protocol.Breadcrumb import io.sentry.kotlin.multiplatform.protocol.SentryId import io.sentry.kotlin.multiplatform.protocol.User import io.sentry.kotlin.multiplatform.protocol.UserFeedback +import kotlinx.coroutines.CancellationException +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.currentCoroutineContext +import kotlinx.coroutines.withContext +import kotlin.coroutines.AbstractCoroutineContextElement +import kotlin.coroutines.CoroutineContext import kotlin.experimental.ExperimentalObjCRefinement import kotlin.native.HiddenFromObjC @@ -111,7 +117,7 @@ public object Sentry { SentryBridge.setUser(user) } - public fun startTransaction(name: String, operation: String): Transaction { + public fun startTransaction(name: String, operation: String): Span { return SentryBridge.startTransaction(name, operation) } @@ -129,3 +135,41 @@ public object Sentry { SentryBridge.close() } } + +public data class SpanContext(val span: Span) : AbstractCoroutineContextElement(SpanContext) { + public companion object Key : CoroutineContext.Key +} + +public fun CoroutineContext.currentSpan(): Span { + return get(SpanContext)?.span ?: throw IllegalStateException("No active Span in context") +} + +public suspend fun withTrace( + name: String, + spanName: String, + block: suspend CoroutineScope.() -> T +): T { + val trace = Sentry.startTransaction(name, spanName) + return withSpan(trace, block) +} + +public suspend fun withSpan(name: String, block: suspend CoroutineScope.() -> T): T { + val span = currentCoroutineContext().currentSpan() + val childSpan = span.startChild(name) + return withSpan(childSpan, block) +} + +public suspend fun withSpan(span: Span, block: suspend CoroutineScope.() -> T): T { + return try { + withContext(SpanContext(span), block) + } catch (e: Throwable) { + if (e is CancellationException) { + span.status = SpanStatus.CANCELLED + } else { + span.status = SpanStatus.INTERNAL_ERROR + } + throw e + } finally { + span.finish() + } +} \ No newline at end of file diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SpanWrapper.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SpanWrapper.kt deleted file mode 100644 index 6e914120..00000000 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SpanWrapper.kt +++ /dev/null @@ -1,3 +0,0 @@ -package io.sentry.kotlin.multiplatform - -public class SpanWrapper(private val span: Span) : Span by span \ No newline at end of file diff --git a/sentry-samples/kmp-app/androidApp/src/main/java/sample/kmp/app/android/MainActivity.kt b/sentry-samples/kmp-app/androidApp/src/main/java/sample/kmp/app/android/MainActivity.kt index 1b693381..aff0f82e 100644 --- a/sentry-samples/kmp-app/androidApp/src/main/java/sample/kmp/app/android/MainActivity.kt +++ b/sentry-samples/kmp-app/androidApp/src/main/java/sample/kmp/app/android/MainActivity.kt @@ -7,12 +7,17 @@ import androidx.appcompat.app.AppCompatActivity import io.sentry.kotlin.multiplatform.Attachment import io.sentry.kotlin.multiplatform.Sentry import io.sentry.kotlin.multiplatform.protocol.Breadcrumb +import io.sentry.kotlin.multiplatform.withSpan +import io.sentry.kotlin.multiplatform.withTrace +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch import sample.kmp.app.LoginImpl import sample.kmp.app.Platform import sample.kmp.app.configureSentryScope import sample.kmp.app.initializeSentry import java.io.FileOutputStream import java.io.IOException +import java.lang.Thread.sleep class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { @@ -34,6 +39,25 @@ class MainActivity : AppCompatActivity() { captureHardCrashBtn.setOnClickListener { LoginImpl.login() } + + GlobalScope.launch { + println(getData()) + } + val trace = Sentry.startTransaction("myTransaction", "myOp") + + } + + private suspend fun getData(): String { + return withTrace("getData", "custom") { + withSpan("getDataSpan") { + sleep(1000) + } + withSpan("getDataSpan2") { + sleep(1000) + } + sleep(5000) + "foo" + } } } diff --git a/sentry-samples/kmp-app/shared/src/commonMain/kotlin/sample.kmp.app/AppSetup.kt b/sentry-samples/kmp-app/shared/src/commonMain/kotlin/sample.kmp.app/AppSetup.kt index 331f1017..63bbd8b5 100644 --- a/sentry-samples/kmp-app/shared/src/commonMain/kotlin/sample.kmp.app/AppSetup.kt +++ b/sentry-samples/kmp-app/shared/src/commonMain/kotlin/sample.kmp.app/AppSetup.kt @@ -26,6 +26,12 @@ fun configureSentryScope() { */ fun initializeSentry(context: Context) { Sentry.init(context, optionsConfiguration()) + val trace = Sentry.startTransaction("App Startup", "App Startup") + var i = 0 + while(i <= 1000000000) { + i += 1 + } + trace.finish() } /** @@ -35,6 +41,12 @@ fun initializeSentry(context: Context) { */ fun initializeSentry() { Sentry.init(optionsConfiguration()) + val trace = Sentry.startTransaction("App Startup", "App Startup") + var i = 0 + while(i <= 1000000) { + i += 1 + } + trace.finish() } /** Returns a shared options configuration */ @@ -47,6 +59,7 @@ private fun optionsConfiguration(): OptionsConfiguration { it.attachViewHierarchy = true it.release = "kmp-release@0.0.1" it.debug = true + it.tracesSampleRate = 1.0 it.failedRequestStatusCodes = listOf(HttpStatusCodeRange(400, 599)) it.failedRequestTargets = listOf("httpbin.org") it.beforeBreadcrumb = { breadcrumb -> @@ -57,6 +70,7 @@ private fun optionsConfiguration(): OptionsConfiguration { if (event.environment == "test") { null } else { + println("HAHA: ${event.exceptions}") event } } From eb5173087d0efab1506ec8238d1e56b12adbc5ac Mon Sep 17 00:00:00 2001 From: buenaflor Date: Tue, 2 May 2023 19:11:37 +0200 Subject: [PATCH 06/43] remove dead code --- .../kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt | 1 - .../kotlin/multiplatform/extensions/SentryOptionsExtensions.kt | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt index 278c1aa1..85e01598 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt @@ -65,7 +65,6 @@ internal actual object SentryBridge { actual fun startTransaction(operation: String, description: String): Span { val cocoaSpan = SentrySDK.startTransactionWithName(operation, description) - return CocoaSpanProvider(cocoaSpan) } diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.kt index bb9bfa9a..3e8e0346 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.kt @@ -46,8 +46,7 @@ internal fun JvmSentryOptions.applyJvmBaseOptions(options: SentryOptions) { setBeforeBreadcrumb { jvmBreadcrumb, _ -> options.beforeBreadcrumb?.invoke(jvmBreadcrumb.toKmpBreadcrumb())?.toJvmBreadcrumb() } - setBeforeSend { jvmSentryEvent, hint -> - println("beforeSend: ${jvmSentryEvent.throwable}") + setBeforeSend { jvmSentryEvent, _ -> if (options.beforeSend == null) { jvmSentryEvent } else { From 385f8ba64f834acd055b3fbbd5822dff97912857 Mon Sep 17 00:00:00 2001 From: buenaflor Date: Tue, 2 May 2023 20:59:44 +0200 Subject: [PATCH 07/43] add basic setup for jvm --- .../CocoaTransactionContextProvider.kt | 25 ++++++ .../kotlin/multiplatform/TypeAliases.kt | 6 +- .../extensions/SentryOptionsExtensions.kt | 6 ++ .../SentrySampleDecisionExtensions.kt | 12 +++ .../TransactionNameSourceExtensions.kt | 29 +++++++ .../kotlin/multiplatform/protocol/SpanId.kt | 25 ++++++ .../JvmTransactionContextProvider.kt | 21 +++++ .../kotlin/multiplatform/TypeAliases.kt | 8 +- .../extensions/SentryOptionsExtensions.kt | 16 +++- .../TransactionNameSourceExtensions.kt | 13 ++++ .../kotlin/multiplatform/protocol/SpanId.kt | 24 ++++++ .../multiplatform/CustomSamplingContext.kt | 5 ++ .../kotlin/multiplatform/SamplingContext.kt | 6 ++ .../sentry/kotlin/multiplatform/SentryKMP.kt | 38 --------- .../kotlin/multiplatform/SentryOptions.kt | 5 ++ .../kotlin/multiplatform/SpanContext.kt | 24 ++++++ .../multiplatform/TransactionContext.kt | 12 +++ .../kotlin/multiplatform/protocol/SpanId.kt | 8 ++ .../protocol/TransactionNameSource.kt | 78 +++++++++++++++++++ .../CustomInstrumentationIntegrationTest.kt | 5 ++ .../kotlin/sample.kmp.app/SentrySetup.kt | 1 + 21 files changed, 326 insertions(+), 41 deletions(-) create mode 100644 sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/CocoaTransactionContextProvider.kt create mode 100644 sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentrySampleDecisionExtensions.kt create mode 100644 sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/TransactionNameSourceExtensions.kt create mode 100644 sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/protocol/SpanId.kt create mode 100644 sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/JvmTransactionContextProvider.kt create mode 100644 sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/TransactionNameSourceExtensions.kt create mode 100644 sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/protocol/SpanId.kt create mode 100644 sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/CustomSamplingContext.kt create mode 100644 sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SamplingContext.kt create mode 100644 sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SpanContext.kt create mode 100644 sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContext.kt create mode 100644 sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/protocol/SpanId.kt create mode 100644 sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/protocol/TransactionNameSource.kt create mode 100644 sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/CustomInstrumentationIntegrationTest.kt diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/CocoaTransactionContextProvider.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/CocoaTransactionContextProvider.kt new file mode 100644 index 00000000..8659818c --- /dev/null +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/CocoaTransactionContextProvider.kt @@ -0,0 +1,25 @@ +package io.sentry.kotlin.multiplatform + +import io.sentry.kotlin.multiplatform.extensions.toBoolean +import io.sentry.kotlin.multiplatform.extensions.toKmp +import io.sentry.kotlin.multiplatform.extensions.toKmpTransactionNameSource +import io.sentry.kotlin.multiplatform.protocol.SentryId +import io.sentry.kotlin.multiplatform.protocol.SpanId +import io.sentry.kotlin.multiplatform.protocol.TransactionNameSource +import kotlinx.cinterop.UnsafeNumber + +internal class CocoaTransactionContextProvider(cocoaTransactionContext: CocoaTransactionContext) : + TransactionContext { + override val name: String = cocoaTransactionContext.name + @OptIn(UnsafeNumber::class) + override val transactionNameSource: TransactionNameSource = + cocoaTransactionContext.nameSource.toKmpTransactionNameSource() + override val sampled: Boolean = cocoaTransactionContext.sampled().toBoolean() + override val parentSampled: Boolean = cocoaTransactionContext.parentSampled().toBoolean() + override val operation: String = cocoaTransactionContext.operation + override val traceId: SentryId = SentryId(cocoaTransactionContext.traceId.toString()) + override val spanId: SpanId = SpanId(cocoaTransactionContext.spanId.toString()) + override val parentSpanId: SpanId? = + cocoaTransactionContext.parentSpanId?.let { SpanId(it.toString()) } + override val description: String? = cocoaTransactionContext.description +} \ No newline at end of file diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/TypeAliases.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/TypeAliases.kt index 53fdec63..77d8edf6 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/TypeAliases.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/TypeAliases.kt @@ -9,7 +9,9 @@ import cocoapods.Sentry.SentryLevel import cocoapods.Sentry.SentryMessage import cocoapods.Sentry.SentryOptions import cocoapods.Sentry.SentryScope +import cocoapods.Sentry.SentrySpanId import cocoapods.Sentry.SentrySpanStatus +import cocoapods.Sentry.SentryTransactionContext import cocoapods.Sentry.SentryUser import cocoapods.Sentry.SentryUserFeedback @@ -24,4 +26,6 @@ internal typealias CocoaUserFeedback = SentryUserFeedback internal typealias CocoaSentryEvent = SentryEvent internal typealias CocoaMessage = SentryMessage internal typealias CocoaSentryException = SentryException -internal typealias CocoaSpanStatus = SentrySpanStatus \ No newline at end of file +internal typealias CocoaSpanStatus = SentrySpanStatus +internal typealias CocoaSpanId = SentrySpanId +internal typealias CocoaTransactionContext = SentryTransactionContext diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.kt index beff66c9..5cf840d3 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.kt @@ -2,6 +2,7 @@ package io.sentry.kotlin.multiplatform.extensions import PrivateSentrySDKOnly.Sentry.PrivateSentrySDKOnly import cocoapods.Sentry.SentryHttpStatusCodeRange +import cocoapods.Sentry.SentrySampleDecision import io.sentry.kotlin.multiplatform.BuildKonfig import io.sentry.kotlin.multiplatform.CocoaSentryEvent import io.sentry.kotlin.multiplatform.CocoaSentryOptions @@ -73,6 +74,11 @@ internal fun CocoaSentryOptions.applyCocoaBaseOptions(options: SentryOptions) { ?.let { options.beforeBreadcrumb?.invoke(it) }?.toCocoaBreadcrumb() } + tracesSampler = { + it?.transactionContext?.nameSource + 1.convert() + } + enableCaptureFailedRequests = options.enableCaptureFailedRequests failedRequestTargets = options.failedRequestTargets failedRequestStatusCodes = options.failedRequestStatusCodes.map { diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentrySampleDecisionExtensions.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentrySampleDecisionExtensions.kt new file mode 100644 index 00000000..20a377f2 --- /dev/null +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentrySampleDecisionExtensions.kt @@ -0,0 +1,12 @@ +package io.sentry.kotlin.multiplatform.extensions + +import cocoapods.Sentry.SentrySampleDecision + +internal fun SentrySampleDecision.toBoolean(): Boolean = when (this) { + SentrySampleDecision.kSentrySampleDecisionNo -> false + SentrySampleDecision.kSentrySampleDecisionUndecided -> false + SentrySampleDecision.kSentrySampleDecisionYes -> true + else -> { + false + } +} \ No newline at end of file diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/TransactionNameSourceExtensions.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/TransactionNameSourceExtensions.kt new file mode 100644 index 00000000..56f66181 --- /dev/null +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/TransactionNameSourceExtensions.kt @@ -0,0 +1,29 @@ +package io.sentry.kotlin.multiplatform.extensions + +import io.sentry.kotlin.multiplatform.protocol.TransactionNameSource +import kotlinx.cinterop.UnsafeNumber +import platform.darwin.NSInteger + +/* +Definition of TransactionNameSource in the Cocoa SDK + +typedef NS_ENUM(NSInteger, SentryTransactionNameSource) { + kSentryTransactionNameSourceCustom = 0, + kSentryTransactionNameSourceUrl, + kSentryTransactionNameSourceRoute, + kSentryTransactionNameSourceView, + kSentryTransactionNameSourceComponent, + kSentryTransactionNameSourceTask +}; + */ + +@OptIn(UnsafeNumber::class) +internal fun NSInteger.toKmpTransactionNameSource() = when (this) { + 0 -> TransactionNameSource.CUSTOM + 1 -> TransactionNameSource.URL + 2 -> TransactionNameSource.ROUTE + 3 -> TransactionNameSource.VIEW + 4 -> TransactionNameSource.COMPONENT + 5 -> TransactionNameSource.TASK + else -> TransactionNameSource.CUSTOM +} diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/protocol/SpanId.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/protocol/SpanId.kt new file mode 100644 index 00000000..57329103 --- /dev/null +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/protocol/SpanId.kt @@ -0,0 +1,25 @@ +package io.sentry.kotlin.multiplatform.protocol + +import io.sentry.kotlin.multiplatform.CocoaSentryId +import io.sentry.kotlin.multiplatform.CocoaSpanId + +public actual data class SpanId actual constructor(val spanIdString: String) { + + public actual companion object { + public actual val EMPTY_ID: SpanId = SpanId("") + } + + private var cocoaSpanId: CocoaSpanId? = null + + init { + cocoaSpanId = if (spanIdString.isEmpty()) { + CocoaSpanId.empty + } else { + CocoaSpanId(spanIdString) + } + } + + actual override fun toString(): String { + return cocoaSpanId.toString() + } +} diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/JvmTransactionContextProvider.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/JvmTransactionContextProvider.kt new file mode 100644 index 00000000..4477ce43 --- /dev/null +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/JvmTransactionContextProvider.kt @@ -0,0 +1,21 @@ +package io.sentry.kotlin.multiplatform + +import io.sentry.kotlin.multiplatform.extensions.toKmp +import io.sentry.kotlin.multiplatform.protocol.SentryId +import io.sentry.kotlin.multiplatform.protocol.SpanId +import io.sentry.kotlin.multiplatform.protocol.TransactionNameSource + +internal class JvmTransactionContextProvider(jvmTransactionContext: JvmTransactionContext) : + TransactionContext { + override val name: String = jvmTransactionContext.name + override val transactionNameSource: TransactionNameSource = + jvmTransactionContext.transactionNameSource.toKmp() + override val sampled: Boolean? = jvmTransactionContext.sampled + override val parentSampled: Boolean? = jvmTransactionContext.parentSampled + override val operation: String = jvmTransactionContext.operation + override val traceId: SentryId = SentryId(jvmTransactionContext.traceId.toString()) + override val spanId: SpanId = SpanId(jvmTransactionContext.spanId.toString()) + override val parentSpanId: SpanId? = + jvmTransactionContext.parentSpanId?.let { SpanId(it.toString()) } + override val description: String? = jvmTransactionContext.description +} \ No newline at end of file diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/TypeAliases.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/TypeAliases.kt index 35fb24cd..eaa04408 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/TypeAliases.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/TypeAliases.kt @@ -7,6 +7,7 @@ import io.sentry.Scope import io.sentry.SentryEvent import io.sentry.SentryLevel import io.sentry.SentryOptions +import io.sentry.SpanId import io.sentry.UserFeedback import io.sentry.protocol.Contexts import io.sentry.protocol.Message @@ -14,6 +15,8 @@ import io.sentry.protocol.SentryException import io.sentry.protocol.SentryId import io.sentry.protocol.User import io.sentry.SpanStatus +import io.sentry.TransactionContext +import io.sentry.protocol.TransactionNameSource internal typealias JvmSentryLevel = SentryLevel internal typealias JvmUser = User @@ -27,4 +30,7 @@ internal typealias JvmSentryEvent = SentryEvent internal typealias JvmMessage = Message internal typealias JvmSentryException = SentryException internal typealias JvmContexts = Contexts -internal typealias JvmSpanStatus = SpanStatus \ No newline at end of file +internal typealias JvmSpanStatus = SpanStatus +internal typealias JvmSpanId = SpanId +internal typealias JvmTransactionContext = TransactionContext +internal typealias JvmTransactionNameSource = TransactionNameSource \ No newline at end of file diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.kt index 3e8e0346..b3cd5e38 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.kt @@ -1,9 +1,13 @@ package io.sentry.kotlin.multiplatform.extensions import io.sentry.kotlin.multiplatform.BuildKonfig +import io.sentry.kotlin.multiplatform.CustomSamplingContext import io.sentry.kotlin.multiplatform.JvmSentryOptions +import io.sentry.kotlin.multiplatform.JvmTransactionContextProvider +import io.sentry.kotlin.multiplatform.SamplingContext import io.sentry.kotlin.multiplatform.SentryEvent import io.sentry.kotlin.multiplatform.SentryOptions +import io.sentry.kotlin.multiplatform.TransactionContextProv internal fun SentryOptions.toJvmSentryOptionsCallback(): (JvmSentryOptions) -> Unit = { it.applyJvmBaseOptions(this) @@ -25,7 +29,6 @@ internal fun SentryOptions.toJvmSentryOptionsCallback(): (JvmSentryOptions) -> U } - /** * Applies the given base SentryOptions to this JvmSentryOption * This avoids code duplication during init on Android @@ -55,4 +58,15 @@ internal fun JvmSentryOptions.applyJvmBaseOptions(options: SentryOptions) { } } } + setTracesSampler { + val jvmTransactionContext = JvmTransactionContextProvider(it.transactionContext) + val transactionContext = TransactionContextProv(jvmTransactionContext) + val customSamplingContext: CustomSamplingContext? = + it.customSamplingContext?.data?.let { customSamplingContext -> + CustomSamplingContext(customSamplingContext) + } + val samplingContext = SamplingContext(transactionContext, customSamplingContext) + // returns null if KMP tracesSampler is null + options.tracesSampler?.invoke(samplingContext) + } } \ No newline at end of file diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/TransactionNameSourceExtensions.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/TransactionNameSourceExtensions.kt new file mode 100644 index 00000000..15cf73a4 --- /dev/null +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/TransactionNameSourceExtensions.kt @@ -0,0 +1,13 @@ +package io.sentry.kotlin.multiplatform.extensions + +import io.sentry.kotlin.multiplatform.JvmTransactionNameSource +import io.sentry.kotlin.multiplatform.protocol.TransactionNameSource + +internal fun JvmTransactionNameSource.toKmp(): TransactionNameSource = when (this) { + JvmTransactionNameSource.COMPONENT -> TransactionNameSource.COMPONENT + JvmTransactionNameSource.ROUTE -> TransactionNameSource.ROUTE + JvmTransactionNameSource.URL -> TransactionNameSource.URL + JvmTransactionNameSource.VIEW -> TransactionNameSource.VIEW + JvmTransactionNameSource.TASK -> TransactionNameSource.TASK + JvmTransactionNameSource.CUSTOM -> TransactionNameSource.CUSTOM +} \ No newline at end of file diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/protocol/SpanId.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/protocol/SpanId.kt new file mode 100644 index 00000000..14c6dda7 --- /dev/null +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/protocol/SpanId.kt @@ -0,0 +1,24 @@ +package io.sentry.kotlin.multiplatform.protocol + +import io.sentry.kotlin.multiplatform.JvmSpanId + +public actual data class SpanId actual constructor(val spanIdString: String) { + + public actual companion object { + public actual val EMPTY_ID: SpanId = SpanId("") + } + + private var jvmSpanId: JvmSpanId? = null + + init { + jvmSpanId = if (spanIdString.isEmpty()) { + JvmSpanId.EMPTY_ID + } else { + JvmSpanId(spanIdString) + } + } + + actual override fun toString(): String { + return jvmSpanId.toString() + } +} diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/CustomSamplingContext.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/CustomSamplingContext.kt new file mode 100644 index 00000000..4f231f97 --- /dev/null +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/CustomSamplingContext.kt @@ -0,0 +1,5 @@ +package io.sentry.kotlin.multiplatform + +public data class CustomSamplingContext( + private val data: MutableMap = mutableMapOf() +) \ No newline at end of file diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SamplingContext.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SamplingContext.kt new file mode 100644 index 00000000..f025d226 --- /dev/null +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SamplingContext.kt @@ -0,0 +1,6 @@ +package io.sentry.kotlin.multiplatform + +public data class SamplingContext( + private val transactionContext: TransactionContext, + private val customSamplingContext: CustomSamplingContext? +) diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryKMP.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryKMP.kt index 3d5769ad..567488db 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryKMP.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryKMP.kt @@ -134,42 +134,4 @@ public object Sentry { public fun close() { SentryBridge.close() } -} - -public data class SpanContext(val span: Span) : AbstractCoroutineContextElement(SpanContext) { - public companion object Key : CoroutineContext.Key -} - -public fun CoroutineContext.currentSpan(): Span { - return get(SpanContext)?.span ?: throw IllegalStateException("No active Span in context") -} - -public suspend fun withTrace( - name: String, - spanName: String, - block: suspend CoroutineScope.() -> T -): T { - val trace = Sentry.startTransaction(name, spanName) - return withSpan(trace, block) -} - -public suspend fun withSpan(name: String, block: suspend CoroutineScope.() -> T): T { - val span = currentCoroutineContext().currentSpan() - val childSpan = span.startChild(name) - return withSpan(childSpan, block) -} - -public suspend fun withSpan(span: Span, block: suspend CoroutineScope.() -> T): T { - return try { - withContext(SpanContext(span), block) - } catch (e: Throwable) { - if (e is CancellationException) { - span.status = SpanStatus.CANCELLED - } else { - span.status = SpanStatus.INTERNAL_ERROR - } - throw e - } finally { - span.finish() - } } \ No newline at end of file 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 452266f2..bb556475 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 @@ -48,6 +48,11 @@ public open class SentryOptions { */ public var tracesSampleRate: Double? = null + /** + * This function is called by TracesSampler to determine if transaction is sampled - meant to be sent to Sentry. + */ + public var tracesSampler: ((SamplingContext) -> Double)? = null + /** Whether to enable or disable automatic session tracking. */ public var enableAutoSessionTracking: Boolean = true diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SpanContext.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SpanContext.kt new file mode 100644 index 00000000..2106b98a --- /dev/null +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SpanContext.kt @@ -0,0 +1,24 @@ +package io.sentry.kotlin.multiplatform + +import io.sentry.kotlin.multiplatform.protocol.SentryId +import io.sentry.kotlin.multiplatform.protocol.SpanId + +/** + * An interface representing the context of a span. + * + * @property operation The name of the operation associated with the span. + * @property traceId Determines which trace the span belongs to. + * @property spanId The unique identifier of the span. + * @property parentSpanId The unique identifier of the span's parent, if any. + * @property description A longer description of the span's operation, which uniquely identifies the span but is + * consistent across instances of the span. + * @property sampled Indicates if the span is sampled. + */ +public interface SpanContext { + public val operation: String + public val traceId: SentryId + public val spanId: SpanId + public val parentSpanId: SpanId? + public val description: String? + public val sampled: Boolean? +} diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContext.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContext.kt new file mode 100644 index 00000000..41505d3e --- /dev/null +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContext.kt @@ -0,0 +1,12 @@ +package io.sentry.kotlin.multiplatform + +import io.sentry.kotlin.multiplatform.protocol.TransactionNameSource + +public class TransactionContextProv constructor(private val transactionContext: TransactionContext) : + TransactionContext by transactionContext + +public interface TransactionContext : SpanContext { + public val name: String + public val transactionNameSource: TransactionNameSource + public val parentSampled: Boolean? +} \ No newline at end of file diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/protocol/SpanId.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/protocol/SpanId.kt new file mode 100644 index 00000000..e4676756 --- /dev/null +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/protocol/SpanId.kt @@ -0,0 +1,8 @@ +package io.sentry.kotlin.multiplatform.protocol + +public expect class SpanId(spanIdString: String) { + public companion object { + public val EMPTY_ID: SpanId + } + override fun toString(): String +} \ No newline at end of file diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/protocol/TransactionNameSource.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/protocol/TransactionNameSource.kt new file mode 100644 index 00000000..1d99ebf8 --- /dev/null +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/protocol/TransactionNameSource.kt @@ -0,0 +1,78 @@ +package io.sentry.kotlin.multiplatform.protocol + +public enum class TransactionNameSource { + /** + * User-defined name + * + * + * Examples: + * + * + * * my_transaction + * + */ + CUSTOM, + + /** + * Raw URL, potentially containing identifiers. + * + * + * Examples: + * + * + * * /auth/login/john123/ + * * GET /auth/login/john123/ + * + */ + URL, + + /** + * Parametrized URL / route + * + * + * Examples: + * + * + * * /auth/login/:userId/ + * * GET /auth/login/{user}/ + * + */ + ROUTE, + + /** + * Name of the view handling the request. + * + * + * Examples: + * + * + * * UserListView + * + */ + VIEW, + + /** + * Named after a software component, such as a function or class name. + * + * + * Examples: + * + * + * * AuthLogin.login + * * LoginActivity.login_button + * + */ + COMPONENT, + + /** + * Name of a background task + * + * + * Examples: + * + * + * * sentry.tasks.do_something + * + */ + TASK; +} diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/CustomInstrumentationIntegrationTest.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/CustomInstrumentationIntegrationTest.kt new file mode 100644 index 00000000..410315ff --- /dev/null +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/CustomInstrumentationIntegrationTest.kt @@ -0,0 +1,5 @@ +package io.sentry.kotlin.multiplatform + +class CustomInstrumentationIntegrationTest : BaseSentryTest() { + +} \ No newline at end of file diff --git a/sentry-samples/kmp-app-spm/shared/src/commonMain/kotlin/sample.kmp.app/SentrySetup.kt b/sentry-samples/kmp-app-spm/shared/src/commonMain/kotlin/sample.kmp.app/SentrySetup.kt index c094d11d..5dcb8128 100644 --- a/sentry-samples/kmp-app-spm/shared/src/commonMain/kotlin/sample.kmp.app/SentrySetup.kt +++ b/sentry-samples/kmp-app-spm/shared/src/commonMain/kotlin/sample.kmp.app/SentrySetup.kt @@ -5,6 +5,7 @@ import io.sentry.kotlin.multiplatform.Context import io.sentry.kotlin.multiplatform.HttpStatusCodeRange import io.sentry.kotlin.multiplatform.OptionsConfiguration import io.sentry.kotlin.multiplatform.Sentry +import io.sentry.kotlin.multiplatform.SpanStatus /** Configure scope applicable to all platforms */ fun configureSentryScope() { From a9c3bb42432927232ef0f44330e479be4256e88e Mon Sep 17 00:00:00 2001 From: buenaflor Date: Tue, 2 May 2023 21:15:04 +0200 Subject: [PATCH 08/43] add tracesSampler for apple --- .../extensions/SentryOptionsExtensions.kt | 31 ++++++++++++++----- .../extensions/SentryOptionsExtensions.kt | 3 +- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.kt index 5cf840d3..7e89c942 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.kt @@ -2,12 +2,15 @@ package io.sentry.kotlin.multiplatform.extensions import PrivateSentrySDKOnly.Sentry.PrivateSentrySDKOnly import cocoapods.Sentry.SentryHttpStatusCodeRange -import cocoapods.Sentry.SentrySampleDecision import io.sentry.kotlin.multiplatform.BuildKonfig import io.sentry.kotlin.multiplatform.CocoaSentryEvent import io.sentry.kotlin.multiplatform.CocoaSentryOptions +import io.sentry.kotlin.multiplatform.CocoaTransactionContextProvider +import io.sentry.kotlin.multiplatform.CustomSamplingContext +import io.sentry.kotlin.multiplatform.SamplingContext import io.sentry.kotlin.multiplatform.SentryEvent import io.sentry.kotlin.multiplatform.SentryOptions +import io.sentry.kotlin.multiplatform.TransactionContextProv import io.sentry.kotlin.multiplatform.nsexception.dropKotlinCrashEvent import kotlinx.cinterop.convert import platform.Foundation.NSNumber @@ -53,7 +56,7 @@ internal fun CocoaSentryOptions.applyCocoaBaseOptions(options: SentryOptions) { sdk?.set("packages", packages) event?.sdk = sdk - + if (options.beforeSend == null) { dropKotlinCrashEvent(event as NSExceptionSentryEvent?) as CocoaSentryEvent? } else { @@ -70,21 +73,33 @@ internal fun CocoaSentryOptions.applyCocoaBaseOptions(options: SentryOptions) { PrivateSentrySDKOnly.setSdkName(sdkName, sdkVersion) beforeBreadcrumb = { cocoaBreadcrumb -> - cocoaBreadcrumb?.toKmpBreadcrumb() - ?.let { options.beforeBreadcrumb?.invoke(it) }?.toCocoaBreadcrumb() + cocoaBreadcrumb?.toKmpBreadcrumb()?.let { options.beforeBreadcrumb?.invoke(it) } + ?.toCocoaBreadcrumb() } tracesSampler = { - it?.transactionContext?.nameSource - 1.convert() + it?.let { + val cocoaTransactionContext = CocoaTransactionContextProvider(it.transactionContext) + val transactionContext = TransactionContextProv(cocoaTransactionContext) + val customSamplingContext: CustomSamplingContext? = + it.customSamplingContext?.values?.let { customSamplingContext -> + val data = customSamplingContext as? MutableMap + data?.let { unwrappedData -> CustomSamplingContext(unwrappedData) } + } + val samplingContext = SamplingContext(transactionContext, customSamplingContext) + // returns null if KMP tracesSampler is null + val sampleRate = options.tracesSampler?.invoke(samplingContext) + sampleRate?.let { unwrappedSampleRate -> + NSNumber(unwrappedSampleRate) + } + } } enableCaptureFailedRequests = options.enableCaptureFailedRequests failedRequestTargets = options.failedRequestTargets failedRequestStatusCodes = options.failedRequestStatusCodes.map { SentryHttpStatusCodeRange( - min = it.min.convert(), - max = it.max.convert() + min = it.min.convert(), max = it.max.convert() ) } } diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.kt index b3cd5e38..82aef108 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.kt @@ -67,6 +67,7 @@ internal fun JvmSentryOptions.applyJvmBaseOptions(options: SentryOptions) { } val samplingContext = SamplingContext(transactionContext, customSamplingContext) // returns null if KMP tracesSampler is null - options.tracesSampler?.invoke(samplingContext) + val sampleRate = options.tracesSampler?.invoke(samplingContext) + sampleRate } } \ No newline at end of file From 7d15ad0bcde5fa6be3a1b3c7782a38c799c93ea9 Mon Sep 17 00:00:00 2001 From: buenaflor Date: Wed, 3 May 2023 02:17:40 +0200 Subject: [PATCH 09/43] add tests --- .../kotlin/multiplatform/CocoaSpanProvider.kt | 11 +- .../CocoaTransactionContextProvider.kt | 3 - .../kotlin/multiplatform/SentryBridge.kt | 15 +- .../kotlin/multiplatform/TypeAliases.kt | 2 + .../extensions/SentryOptionsExtensions.kt | 2 +- .../SentrySampleDecisionExtensions.kt | 5 + .../TransactionContextExtensions.kt | 19 ++ .../TransactionNameSourceExtensions.kt | 31 ++- .../kotlin/multiplatform/JvmSpanProvider.kt | 7 + .../kotlin/multiplatform/SentryBridge.kt | 20 +- .../multiplatform/CustomSamplingContext.kt | 2 +- .../kotlin/multiplatform/SamplingContext.kt | 4 +- .../kotlin/multiplatform/SentryBridge.kt | 6 +- .../sentry/kotlin/multiplatform/SentryKMP.kt | 5 + .../kotlin/multiplatform/SentryOptions.kt | 6 +- .../io/sentry/kotlin/multiplatform/Span.kt | 8 + .../kotlin/multiplatform/Transaction.kt | 29 -- .../TracesSamplerRateIntegrationTest.kt | 119 +++++++++ .../multiplatform/TracesSamplerRateTest.kt | 251 ++++++++++++++++++ .../utils/MockSamplingContextFactory.kt | 36 +++ .../sample/kmp/app/android/MainActivity.kt | 5 + .../kotlin/sample.kmp.app/SentrySetup.kt | 13 + 22 files changed, 539 insertions(+), 60 deletions(-) create mode 100644 sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/TransactionContextExtensions.kt delete mode 100644 sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Transaction.kt create mode 100644 sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TracesSamplerRateIntegrationTest.kt create mode 100644 sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TracesSamplerRateTest.kt create mode 100644 sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/utils/MockSamplingContextFactory.kt diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/CocoaSpanProvider.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/CocoaSpanProvider.kt index 7c32cf00..11306778 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/CocoaSpanProvider.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/CocoaSpanProvider.kt @@ -3,6 +3,7 @@ package io.sentry.kotlin.multiplatform import cocoapods.Sentry.SentrySpanProtocol import io.sentry.kotlin.multiplatform.extensions.toCocoa import io.sentry.kotlin.multiplatform.extensions.toKmp +import io.sentry.kotlin.multiplatform.protocol.SpanId internal class CocoaSpanProvider(private val cocoaSpan: SentrySpanProtocol) : Span { override fun startChild(operation: String): Span { @@ -11,7 +12,8 @@ internal class CocoaSpanProvider(private val cocoaSpan: SentrySpanProtocol) : Sp } override fun startChild(operation: String, description: String?): Span { - val cocoaSpan = cocoaSpan.startChildWithOperation(operation = operation, description = description) + val cocoaSpan = + cocoaSpan.startChildWithOperation(operation = operation, description = description) return CocoaSpanProvider(cocoaSpan) } @@ -28,11 +30,13 @@ internal class CocoaSpanProvider(private val cocoaSpan: SentrySpanProtocol) : Sp set(value) { cocoaSpan.operation = value } + override var description: String? get() = cocoaSpan.spanDescription set(value) { cocoaSpan.setSpanDescription(value) } + override var status: SpanStatus? get() = cocoaSpan.status.toKmp() set(value) { @@ -40,6 +44,11 @@ internal class CocoaSpanProvider(private val cocoaSpan: SentrySpanProtocol) : Sp cocoaSpan.status = it.toCocoa() } } + + override val spanId: SpanId = SpanId(cocoaSpan.spanId.toString()) + + override val parentSpanId: SpanId? = cocoaSpan.parentSpanId?.let { SpanId(it.toString()) } + override fun setTag(key: String, value: String) { cocoaSpan.setTagValue(value = value, forKey = key) } diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/CocoaTransactionContextProvider.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/CocoaTransactionContextProvider.kt index 8659818c..40e83a60 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/CocoaTransactionContextProvider.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/CocoaTransactionContextProvider.kt @@ -1,17 +1,14 @@ package io.sentry.kotlin.multiplatform import io.sentry.kotlin.multiplatform.extensions.toBoolean -import io.sentry.kotlin.multiplatform.extensions.toKmp import io.sentry.kotlin.multiplatform.extensions.toKmpTransactionNameSource import io.sentry.kotlin.multiplatform.protocol.SentryId import io.sentry.kotlin.multiplatform.protocol.SpanId import io.sentry.kotlin.multiplatform.protocol.TransactionNameSource -import kotlinx.cinterop.UnsafeNumber internal class CocoaTransactionContextProvider(cocoaTransactionContext: CocoaTransactionContext) : TransactionContext { override val name: String = cocoaTransactionContext.name - @OptIn(UnsafeNumber::class) override val transactionNameSource: TransactionNameSource = cocoaTransactionContext.nameSource.toKmpTransactionNameSource() override val sampled: Boolean = cocoaTransactionContext.sampled().toBoolean() diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt index 85e01598..32839f53 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt @@ -2,6 +2,7 @@ package io.sentry.kotlin.multiplatform import cocoapods.Sentry.SentrySDK import cocoapods.Sentry.SentrySpanProtocol +import io.sentry.kotlin.multiplatform.extensions.toCocoa import io.sentry.kotlin.multiplatform.extensions.toCocoaBreadcrumb import io.sentry.kotlin.multiplatform.extensions.toCocoaUser import io.sentry.kotlin.multiplatform.extensions.toCocoaUserFeedback @@ -63,11 +64,21 @@ internal actual object SentryBridge { SentrySDK.setUser(user?.toCocoaUser()) } - actual fun startTransaction(operation: String, description: String): Span { - val cocoaSpan = SentrySDK.startTransactionWithName(operation, description) + actual fun startTransaction(name: String, operation: String): Span { + val cocoaSpan = SentrySDK.startTransactionWithName(name, operation) return CocoaSpanProvider(cocoaSpan) } + actual fun startTransaction(transactionContext: TransactionContext): Span { + val cocoaTransaction = SentrySDK.startTransactionWithContext(transactionContext.toCocoa()) + return CocoaSpanProvider(cocoaTransaction) + } + + actual fun startTransaction(transactionContext: TransactionContext, customSamplingContext: CustomSamplingContext): Span { + val cocoaTransaction = SentrySDK.startTransactionWithContext(transactionContext.toCocoa(), customSamplingContext.data as Map) + return CocoaSpanProvider(cocoaTransaction) + } + actual fun close() { SentrySDK.close() } diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/TypeAliases.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/TypeAliases.kt index 77d8edf6..8713f8bf 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/TypeAliases.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/TypeAliases.kt @@ -8,6 +8,7 @@ import cocoapods.Sentry.SentryId import cocoapods.Sentry.SentryLevel import cocoapods.Sentry.SentryMessage import cocoapods.Sentry.SentryOptions +import cocoapods.Sentry.SentrySampleDecision import cocoapods.Sentry.SentryScope import cocoapods.Sentry.SentrySpanId import cocoapods.Sentry.SentrySpanStatus @@ -29,3 +30,4 @@ internal typealias CocoaSentryException = SentryException internal typealias CocoaSpanStatus = SentrySpanStatus internal typealias CocoaSpanId = SentrySpanId internal typealias CocoaTransactionContext = SentryTransactionContext +internal typealias CocoaSampleDecision = SentrySampleDecision diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.kt index 7e89c942..a61144b4 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.kt @@ -83,7 +83,7 @@ internal fun CocoaSentryOptions.applyCocoaBaseOptions(options: SentryOptions) { val transactionContext = TransactionContextProv(cocoaTransactionContext) val customSamplingContext: CustomSamplingContext? = it.customSamplingContext?.values?.let { customSamplingContext -> - val data = customSamplingContext as? MutableMap + val data = customSamplingContext as? Map data?.let { unwrappedData -> CustomSamplingContext(unwrappedData) } } val samplingContext = SamplingContext(transactionContext, customSamplingContext) diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentrySampleDecisionExtensions.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentrySampleDecisionExtensions.kt index 20a377f2..099ba308 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentrySampleDecisionExtensions.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentrySampleDecisionExtensions.kt @@ -9,4 +9,9 @@ internal fun SentrySampleDecision.toBoolean(): Boolean = when (this) { else -> { false } +} + +internal fun Boolean.toSampleDecision(): SentrySampleDecision = when (this) { + false -> SentrySampleDecision.kSentrySampleDecisionNo + true -> SentrySampleDecision.kSentrySampleDecisionYes } \ No newline at end of file diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/TransactionContextExtensions.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/TransactionContextExtensions.kt new file mode 100644 index 00000000..5311010c --- /dev/null +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/TransactionContextExtensions.kt @@ -0,0 +1,19 @@ +package io.sentry.kotlin.multiplatform.extensions + +import io.sentry.kotlin.multiplatform.CocoaSampleDecision +import io.sentry.kotlin.multiplatform.CocoaSentryId +import io.sentry.kotlin.multiplatform.CocoaSpanId +import io.sentry.kotlin.multiplatform.CocoaTransactionContext +import io.sentry.kotlin.multiplatform.TransactionContext +import kotlinx.cinterop.UnsafeNumber + +@OptIn(UnsafeNumber::class) +internal fun TransactionContext.toCocoa() = CocoaTransactionContext( + name = name, + operation = operation, + traceId = CocoaSentryId(traceId.toString()), + spanId = CocoaSpanId(spanId.toString()), + parentSpanId = parentSpanId?.let { CocoaSpanId(it.toString()) }, + parentSampled = parentSampled?.toSampleDecision() + ?: CocoaSampleDecision.kSentrySampleDecisionNo, +) diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/TransactionNameSourceExtensions.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/TransactionNameSourceExtensions.kt index 56f66181..01496c71 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/TransactionNameSourceExtensions.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/TransactionNameSourceExtensions.kt @@ -18,12 +18,27 @@ typedef NS_ENUM(NSInteger, SentryTransactionNameSource) { */ @OptIn(UnsafeNumber::class) -internal fun NSInteger.toKmpTransactionNameSource() = when (this) { - 0 -> TransactionNameSource.CUSTOM - 1 -> TransactionNameSource.URL - 2 -> TransactionNameSource.ROUTE - 3 -> TransactionNameSource.VIEW - 4 -> TransactionNameSource.COMPONENT - 5 -> TransactionNameSource.TASK - else -> TransactionNameSource.CUSTOM +internal fun NSInteger.toKmpTransactionNameSource(): TransactionNameSource { + val transactionNameSource = when (this.toInt()) { + 0 -> TransactionNameSource.CUSTOM + 1 -> TransactionNameSource.URL + 2 -> TransactionNameSource.ROUTE + 3 -> TransactionNameSource.VIEW + 4 -> TransactionNameSource.COMPONENT + 5 -> TransactionNameSource.TASK + else -> TransactionNameSource.CUSTOM + } + return transactionNameSource +} + +internal fun TransactionNameSource.toNSInteger(): NSInteger { + val transactionNameSource = when (this) { + TransactionNameSource.CUSTOM -> 0 + TransactionNameSource.URL -> 1 + TransactionNameSource.ROUTE -> 2 + TransactionNameSource.VIEW -> 3 + TransactionNameSource.COMPONENT -> 4 + TransactionNameSource.TASK -> 5 + } + return transactionNameSource } diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/JvmSpanProvider.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/JvmSpanProvider.kt index 381c5083..1fe753df 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/JvmSpanProvider.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/JvmSpanProvider.kt @@ -3,6 +3,7 @@ package io.sentry.kotlin.multiplatform import io.sentry.ISpan import io.sentry.kotlin.multiplatform.extensions.toJvm import io.sentry.kotlin.multiplatform.extensions.toKmp +import io.sentry.kotlin.multiplatform.protocol.SpanId internal class JvmSpanProvider(private val jvmSpan: ISpan) : Span { override fun startChild(operation: String): Span { @@ -38,6 +39,12 @@ internal class JvmSpanProvider(private val jvmSpan: ISpan) : Span { set(value) { jvmSpan.status = value?.toJvm() } + + override val spanId: SpanId = SpanId(jvmSpan.spanContext.spanId.toString()) + + override val parentSpanId: SpanId? = + jvmSpan.spanContext.parentSpanId?.let { SpanId(it.toString()) } + override fun setTag(key: String, value: String) { jvmSpan.setTag(key, value) } diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt index ccd81c9d..cb1bfd2f 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt @@ -1,12 +1,6 @@ package io.sentry.kotlin.multiplatform -import io.sentry.ITransaction import io.sentry.Sentry -import io.sentry.SentryDateProvider -import io.sentry.SentryInstantDate -import io.sentry.SentryLongDate -import io.sentry.SpanStatus -import io.sentry.TransactionContext import io.sentry.kotlin.multiplatform.extensions.toJvmBreadcrumb import io.sentry.kotlin.multiplatform.extensions.toJvmUser import io.sentry.kotlin.multiplatform.extensions.toJvmUserFeedback @@ -63,8 +57,18 @@ internal actual object SentryBridge { Sentry.setUser(user?.toJvmUser()) } - actual fun startTransaction(operation: String, description: String): Span { - val jvmTransaction = Sentry.startTransaction(operation, description) + actual fun startTransaction(name: String, operation: String): Span { + val jvmTransaction = Sentry.startTransaction(name, operation) + return JvmSpanProvider(jvmTransaction) + } + + actual fun startTransaction(transactionContext: TransactionContext): Span { + val jvmTransaction = Sentry.startTransaction(transactionContext.toJvmTransactionContext()) + return JvmSpanProvider(jvmTransaction) + } + + actual fun startTransaction(transactionContext: TransactionContext, customSamplingContext: CustomSamplingContext): Span { + val jvmTransaction = Sentry.startTransaction(transactionContext.toJvmTransactionContext(), customSamplingContext.toJvmCustomSamplingContext()) return JvmSpanProvider(jvmTransaction) } diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/CustomSamplingContext.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/CustomSamplingContext.kt index 4f231f97..21631388 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/CustomSamplingContext.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/CustomSamplingContext.kt @@ -1,5 +1,5 @@ package io.sentry.kotlin.multiplatform public data class CustomSamplingContext( - private val data: MutableMap = mutableMapOf() + public val data: Map = mapOf() ) \ No newline at end of file diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SamplingContext.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SamplingContext.kt index f025d226..3c8acba8 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SamplingContext.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SamplingContext.kt @@ -1,6 +1,6 @@ package io.sentry.kotlin.multiplatform public data class SamplingContext( - private val transactionContext: TransactionContext, - private val customSamplingContext: CustomSamplingContext? + public val transactionContext: TransactionContext, + public val customSamplingContext: CustomSamplingContext? ) diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt index 39cb5e01..a2b42dc5 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt @@ -27,7 +27,11 @@ internal expect object SentryBridge { fun setUser(user: User?) - fun startTransaction(operation: String, description: String): Span + fun startTransaction(name: String, operation: String): Span + + fun startTransaction(transactionContext: TransactionContext): Span + + fun startTransaction(transactionContext: TransactionContext, customSamplingContext: CustomSamplingContext): Span fun close() } diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryKMP.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryKMP.kt index 567488db..2c8d7787 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryKMP.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryKMP.kt @@ -121,6 +121,11 @@ public object Sentry { return SentryBridge.startTransaction(name, operation) } + public fun startTransaction(name: String, operation: String, description: String): Span { + return SentryBridge.startTransaction(name, operation) + } + + /** * Throws a RuntimeException, useful for testing. */ 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 bb556475..f8a2b461 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 @@ -48,10 +48,8 @@ public open class SentryOptions { */ public var tracesSampleRate: Double? = null - /** - * This function is called by TracesSampler to determine if transaction is sampled - meant to be sent to Sentry. - */ - public var tracesSampler: ((SamplingContext) -> Double)? = null + /** This function is called by TracesSampler to determine if transaction is sampled - meant to be sent to Sentry. */ + public var tracesSampler: ((SamplingContext) -> Double?)? = null /** Whether to enable or disable automatic session tracking. */ public var enableAutoSessionTracking: Boolean = true diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Span.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Span.kt index 78c218b5..25e07095 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Span.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Span.kt @@ -1,5 +1,7 @@ package io.sentry.kotlin.multiplatform +import io.sentry.kotlin.multiplatform.protocol.SpanId + public interface Span { /** * Starts a child Span. @@ -37,6 +39,12 @@ public interface Span { /** The span status. */ public var status: SpanStatus? + /** The span spanId. */ + public val spanId: SpanId + + /** The span parentSpanId. */ + public val parentSpanId: SpanId? + /** * Sets the tag on span or transaction. * diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Transaction.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Transaction.kt deleted file mode 100644 index 203e4b8a..00000000 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Transaction.kt +++ /dev/null @@ -1,29 +0,0 @@ -package io.sentry.kotlin.multiplatform - -import io.sentry.kotlin.multiplatform.protocol.SentryId - -public interface Transaction : Span { - /** The transaction name. */ - public var name: String - - /** - * Returns if transaction is sampled. - * - * @return is sampled - */ - public fun isSampled(): Boolean? - - /** - * Returns the latest span that is not finished. - * - * @return span or null if not found. - */ - public fun getLatestActiveSpan(): Span - - /** - * Returns transaction's event id. - * - * @return the event id - */ - public fun getEventId(): SentryId -} diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TracesSamplerRateIntegrationTest.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TracesSamplerRateIntegrationTest.kt new file mode 100644 index 00000000..ff47ffdc --- /dev/null +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TracesSamplerRateIntegrationTest.kt @@ -0,0 +1,119 @@ +package io.sentry.kotlin.multiplatform + +import io.sentry.kotlin.multiplatform.utils.fakeDsn +import kotlin.test.Test +import kotlin.test.assertEquals + +class TracesSamplerRateIntegrationTest: BaseSentryTest() { + + @Test + fun `tracesSampler can receive correct TransactionContext name`() { + val expectedName = "test" + var actualName = "" + sentryInit { + it.dsn = fakeDsn + it.tracesSampler = { context -> + actualName = context.transactionContext.name + null + } + } + val transaction = Sentry.startTransaction("test", "testOperation") + transaction.finish() + assertEquals(expectedName, actualName) + } + + @Test + fun `tracesSampler can receive correct TransactionContext spanId`() { + var actualSpanId = "" + sentryInit { + it.dsn = fakeDsn + it.tracesSampler = { context -> + actualSpanId = context.transactionContext.spanId.toString() + null + } + } + val transaction = Sentry.startTransaction("test", "testOperation") + transaction.finish() + assertEquals(transaction.spanId.toString(), actualSpanId) + } + + @Test + fun `tracesSampler can receive correct TransactionContext parentSpanId`() { + var actualParentSpanId = "" + sentryInit { + it.dsn = fakeDsn + it.tracesSampler = { context -> + actualParentSpanId = context.transactionContext.parentSpanId.toString() + null + } + } + val transaction = Sentry.startTransaction("test", "testOperation") + transaction.finish() + assertEquals(transaction.parentSpanId?.toString(), actualParentSpanId) + } + + @Test + fun `tracesSampler can receive correct TransactionContext description`() { + val expectedDescription = "test" + var actualDescription: String? = "" + sentryInit { + it.dsn = fakeDsn + it.tracesSampler = { context -> + actualDescription = context.transactionContext.description + null + } + } + val transaction = Sentry.startTransaction("test", "testOperation") + transaction.description = expectedDescription + transaction.finish() + assertEquals(expectedDescription, actualDescription) + } + + @Test + fun `tracesSampler can receive correct TransactionContext operation`() { + val expectedOperation = "testOperation" + var actualOperation = "" + sentryInit { + it.dsn = fakeDsn + it.tracesSampler = { context -> + actualOperation = context.transactionContext.operation + null + } + } + val transaction = Sentry.startTransaction("test", "testOperation") + transaction.finish() + assertEquals(expectedOperation, actualOperation) + } + + @Test + fun `tracesSampler can receive correct TransactionContext sampled`() { + val expectedSampled = null + var actualSampled: Boolean? = false + sentryInit { + it.dsn = fakeDsn + it.tracesSampler = { context -> + actualSampled = context.transactionContext.sampled + null + } + } + val transaction = Sentry.startTransaction("test", "testOperation") + transaction.finish() + assertEquals(expectedSampled, actualSampled) + } + + @Test + fun `tracesSampler can receive correct TransactionContext parentSampled`() { + val expectedSampled = null + var actualSampled: Boolean? = false + sentryInit { + it.dsn = fakeDsn + it.tracesSampler = { context -> + actualSampled = context.transactionContext.parentSampled + null + } + } + val transaction = Sentry.startTransaction("test", "testOperation") + transaction.finish() + assertEquals(expectedSampled, actualSampled) + } +} \ No newline at end of file diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TracesSamplerRateTest.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TracesSamplerRateTest.kt new file mode 100644 index 00000000..ec2624a0 --- /dev/null +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TracesSamplerRateTest.kt @@ -0,0 +1,251 @@ +package io.sentry.kotlin.multiplatform + +import io.sentry.kotlin.multiplatform.protocol.SentryId +import io.sentry.kotlin.multiplatform.protocol.SpanId +import io.sentry.kotlin.multiplatform.protocol.TransactionNameSource +import io.sentry.kotlin.multiplatform.utils.createMockCustomSamplingContext +import io.sentry.kotlin.multiplatform.utils.createMockTransactionContext +import kotlin.test.BeforeTest +import kotlin.test.Test +import kotlin.test.assertEquals + +class MockTransactionContext( + override val operation: String, + override val traceId: SentryId, + override val spanId: SpanId, + override val parentSpanId: SpanId?, + override val description: String?, + override val sampled: Boolean?, + override val name: String, + override val transactionNameSource: TransactionNameSource, + override val parentSampled: Boolean? +) : TransactionContext + +class TracesSamplerRateTest { + private lateinit var mockTransactionContext: TransactionContext + private lateinit var mockCustomSamplingContext: CustomSamplingContext + + @BeforeTest + fun setup() { + mockTransactionContext = createMockTransactionContext() + mockCustomSamplingContext = createMockCustomSamplingContext() + } + + @Test + fun `tracesSampler can return null sample rate`() { + val options = SentryOptions() + options.tracesSampler = { + null + } + val samplingContext = SamplingContext( + transactionContext = mockTransactionContext, + customSamplingContext = mockCustomSamplingContext + ) + val sampleRate = options.tracesSampler?.invoke(samplingContext) + assertEquals(null, sampleRate) + } + + @Test + fun `tracesSampler can return sample rate`() { + val options = SentryOptions() + options.tracesSampler = { + 0.5 + } + val samplingContext = SamplingContext( + transactionContext = mockTransactionContext, + customSamplingContext = mockCustomSamplingContext + ) + val sampleRate = options.tracesSampler?.invoke(samplingContext) + assertEquals(0.5, sampleRate) + } + + @Test + fun `tracesSampler can return different sample rate`() { + val options = SentryOptions() + options.tracesSampler = { + if (it.transactionContext.name == "test") { + 0.5 + } else { + 0.1 + } + } + + // Assert that the sample rate is 0.5 + val samplingContext = SamplingContext( + transactionContext = mockTransactionContext, + customSamplingContext = mockCustomSamplingContext + ) + val sampleRate = options.tracesSampler?.invoke(samplingContext) + assertEquals(0.5, sampleRate) + + // Assert that the sample rate is 0.1 + val differentSamplingContext = SamplingContext( + transactionContext = createMockTransactionContext(name = "different"), + customSamplingContext = mockCustomSamplingContext + ) + val differentSampleRate = options.tracesSampler?.invoke(differentSamplingContext) + assertEquals(0.1, differentSampleRate) + } + + @Test + fun `tracerSampler returns correct TransactionContext name`() { + val options = SentryOptions() + val expectedName = "test" + var actualName = "" + options.tracesSampler = { + actualName = it.transactionContext.name + null + } + + val samplingContext = SamplingContext( + transactionContext = mockTransactionContext, + customSamplingContext = mockCustomSamplingContext + ) + options.tracesSampler?.invoke(samplingContext) + assertEquals(expectedName, actualName) + } + + @Test + fun `tracerSampler returns correct TransactionContext spanId`() { + val options = SentryOptions() + val expectedSpanId = mockTransactionContext.spanId + var actualSpanId: SpanId? = null + options.tracesSampler = { + actualSpanId = it.transactionContext.spanId + null + } + + val samplingContext = SamplingContext( + transactionContext = mockTransactionContext, + customSamplingContext = mockCustomSamplingContext + ) + options.tracesSampler?.invoke(samplingContext) + assertEquals(expectedSpanId, actualSpanId) + } + + @Test + fun `tracerSampler returns correct TransactionContext parentSpanId`() { + val options = SentryOptions() + val expectedParentSpanId = mockTransactionContext.parentSpanId + var actualParentSpanId: SpanId? = null + options.tracesSampler = { + actualParentSpanId = it.transactionContext.parentSpanId + null + } + + val samplingContext = SamplingContext( + transactionContext = mockTransactionContext, + customSamplingContext = mockCustomSamplingContext + ) + options.tracesSampler?.invoke(samplingContext) + assertEquals(expectedParentSpanId, actualParentSpanId) + } + + @Test + fun `tracerSampler returns correct TransactionContext description`() { + val options = SentryOptions() + val expectedDescription = mockTransactionContext.description + var actualDescription: String? = null + options.tracesSampler = { + actualDescription = it.transactionContext.description + null + } + + val samplingContext = SamplingContext( + transactionContext = mockTransactionContext, + customSamplingContext = mockCustomSamplingContext + ) + options.tracesSampler?.invoke(samplingContext) + assertEquals(expectedDescription, actualDescription) + } + + @Test + fun `tracerSampler returns correct TransactionContext sampled`() { + val options = SentryOptions() + val expectedSampled = mockTransactionContext.sampled + var actualSampled: Boolean? = null + options.tracesSampler = { + actualSampled = it.transactionContext.sampled + null + } + + val samplingContext = SamplingContext( + transactionContext = mockTransactionContext, + customSamplingContext = mockCustomSamplingContext + ) + options.tracesSampler?.invoke(samplingContext) + assertEquals(expectedSampled, actualSampled) + } + + @Test + fun `tracerSampler returns correct TransactionContext parentSampled`() { + val options = SentryOptions() + val expectedParentSampled = mockTransactionContext.parentSampled + var actualParentSampled: Boolean? = null + options.tracesSampler = { + actualParentSampled = it.transactionContext.parentSampled + null + } + + val samplingContext = SamplingContext( + transactionContext = mockTransactionContext, + customSamplingContext = mockCustomSamplingContext + ) + options.tracesSampler?.invoke(samplingContext) + assertEquals(expectedParentSampled, actualParentSampled) + } + + @Test + fun `tracerSampler returns correct TransactionContext operation`() { + val options = SentryOptions() + val expectedOperation = mockTransactionContext.operation + var actualOperation: String? = null + options.tracesSampler = { + actualOperation = it.transactionContext.operation + null + } + + val samplingContext = SamplingContext( + transactionContext = mockTransactionContext, + customSamplingContext = mockCustomSamplingContext + ) + options.tracesSampler?.invoke(samplingContext) + assertEquals(expectedOperation, actualOperation) + } + + @Test + fun `tracerSampler returns correct TransactionContext transactionNameSource`() { + val options = SentryOptions() + val expectedTransactionNameSource = mockTransactionContext.transactionNameSource + var actualTransactionNameSource: TransactionNameSource? = null + options.tracesSampler = { + actualTransactionNameSource = it.transactionContext.transactionNameSource + null + } + + val samplingContext = SamplingContext( + transactionContext = mockTransactionContext, + customSamplingContext = mockCustomSamplingContext + ) + options.tracesSampler?.invoke(samplingContext) + assertEquals(expectedTransactionNameSource, actualTransactionNameSource) + } + + @Test + fun `tracerSampler returns correct CustomSamplingContext`() { + val options = SentryOptions() + val expectedData = mockCustomSamplingContext.data + var actualData: Map? = null + options.tracesSampler = { + actualData = it.customSamplingContext?.data + null + } + + val samplingContext = SamplingContext( + transactionContext = mockTransactionContext, + customSamplingContext = mockCustomSamplingContext, + ) + options.tracesSampler?.invoke(samplingContext) + assertEquals(expectedData, actualData) + } +} \ No newline at end of file diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/utils/MockSamplingContextFactory.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/utils/MockSamplingContextFactory.kt new file mode 100644 index 00000000..7b0e182b --- /dev/null +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/utils/MockSamplingContextFactory.kt @@ -0,0 +1,36 @@ +package io.sentry.kotlin.multiplatform.utils + +import io.sentry.kotlin.multiplatform.CustomSamplingContext +import io.sentry.kotlin.multiplatform.MockTransactionContext +import io.sentry.kotlin.multiplatform.TransactionContext +import io.sentry.kotlin.multiplatform.protocol.SentryId +import io.sentry.kotlin.multiplatform.protocol.SpanId +import io.sentry.kotlin.multiplatform.protocol.TransactionNameSource + +fun createMockTransactionContext( + operation: String = "test", + traceId: SentryId = SentryId.EMPTY_ID, + spanId: SpanId = SpanId.EMPTY_ID, + parentSpanId: SpanId? = SpanId("123"), + description: String? = "test description", + sampled: Boolean? = null, + name: String = "test", + transactionNameSource: TransactionNameSource = TransactionNameSource.TASK, + parentSampled: Boolean? = null +): TransactionContext { + return MockTransactionContext( + operation = operation, + traceId = traceId, + spanId = spanId, + parentSpanId = parentSpanId, + description = description, + sampled = sampled, + name = name, + transactionNameSource = transactionNameSource, + parentSampled = parentSampled + ) +} + +fun createMockCustomSamplingContext(data: Map = mapOf("test" to "test")): CustomSamplingContext { + return CustomSamplingContext(data) +} \ No newline at end of file diff --git a/sentry-samples/kmp-app-spm/androidApp/src/main/java/sample/kmp/app/android/MainActivity.kt b/sentry-samples/kmp-app-spm/androidApp/src/main/java/sample/kmp/app/android/MainActivity.kt index 1b693381..ed05c387 100644 --- a/sentry-samples/kmp-app-spm/androidApp/src/main/java/sample/kmp/app/android/MainActivity.kt +++ b/sentry-samples/kmp-app-spm/androidApp/src/main/java/sample/kmp/app/android/MainActivity.kt @@ -13,6 +13,7 @@ import sample.kmp.app.configureSentryScope import sample.kmp.app.initializeSentry import java.io.FileOutputStream import java.io.IOException +import java.lang.Thread.sleep class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { @@ -34,6 +35,10 @@ class MainActivity : AppCompatActivity() { captureHardCrashBtn.setOnClickListener { LoginImpl.login() } + + val transaction = Sentry.startTransaction("adsaa", "activity") + sleep(5000) + transaction.finish() } } diff --git a/sentry-samples/kmp-app-spm/shared/src/commonMain/kotlin/sample.kmp.app/SentrySetup.kt b/sentry-samples/kmp-app-spm/shared/src/commonMain/kotlin/sample.kmp.app/SentrySetup.kt index 5dcb8128..7ce97e2b 100644 --- a/sentry-samples/kmp-app-spm/shared/src/commonMain/kotlin/sample.kmp.app/SentrySetup.kt +++ b/sentry-samples/kmp-app-spm/shared/src/commonMain/kotlin/sample.kmp.app/SentrySetup.kt @@ -60,5 +60,18 @@ private fun optionsConfiguration(): OptionsConfiguration { event } } + it.tracesSampler = { context -> + println("TEST: ${context.transactionContext.transactionNameSource}") + println("TEST: ${context.transactionContext.operation}") + println("TEST: ${context.transactionContext.name}") + println("TEST: ${context.transactionContext.parentSpanId}") + println("TEST: ${context.transactionContext.spanId}") + println("TEST: ${context.transactionContext.traceId}") + println("TEST: ${context.transactionContext.sampled}") + println("TEST: ${context.transactionContext.parentSampled}") + println("TEST: ${context.transactionContext.description}") + println("TEST: ${context.transactionContext.parentSpanId}") + 1.0 + } } } From 71c8ba449e378192055f9c9243cf628bb0011857 Mon Sep 17 00:00:00 2001 From: buenaflor Date: Thu, 4 May 2023 17:44:40 +0200 Subject: [PATCH 10/43] add tests and sample code --- .../CocoaTransactionContextProvider.kt | 2 +- .../kotlin/multiplatform/SentryBridge.kt | 12 ++-- .../extensions/SentryOptionsExtensions.kt | 16 ++--- .../SentrySampleDecisionExtensions.kt | 2 +- .../TransactionContextExtensions.kt | 19 ------ .../TransactionNameSourceExtensions.kt | 14 +---- .../JvmTransactionContextProvider.kt | 4 +- .../kotlin/multiplatform/SentryBridge.kt | 10 +-- .../extensions/SentryOptionsExtensions.kt | 15 ++--- .../multiplatform/CustomSamplingContext.kt | 5 -- .../kotlin/multiplatform/SamplingContext.kt | 1 - .../kotlin/multiplatform/SentryBridge.kt | 4 +- .../sentry/kotlin/multiplatform/SentryKMP.kt | 29 ++++++++- .../kotlin/multiplatform/SpanContext.kt | 2 +- .../multiplatform/TransactionContext.kt | 4 +- .../CustomInstrumentationIntegrationTest.kt | 5 -- .../multiplatform/TracesSamplerRateTest.kt | 39 +----------- ...nTest.kt => TransactionIntegrationTest.kt} | 63 ++++++++++++------- .../utils/MockSamplingContextFactory.kt | 9 +-- .../kotlin/sample.kmp.app/LoginImpl.kt | 3 + .../kotlin/sample.kmp.app/SentrySetup.kt | 1 + .../models/AuthenticationViewModel.kt | 3 + .../sentry.kmp.demo/sentry/SentrySetup.kt | 1 + .../sample/kmp/app/android/MainActivity.kt | 4 -- .../kotlin/sample.kmp.app/LoginImpl.kt | 3 + .../kotlin/sample.kmp.app/SentrySetup.kt | 14 +---- 26 files changed, 116 insertions(+), 168 deletions(-) delete mode 100644 sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/TransactionContextExtensions.kt delete mode 100644 sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/CustomSamplingContext.kt delete mode 100644 sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/CustomInstrumentationIntegrationTest.kt rename sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/{TracesSamplerRateIntegrationTest.kt => TransactionIntegrationTest.kt} (61%) diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/CocoaTransactionContextProvider.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/CocoaTransactionContextProvider.kt index 40e83a60..6990f999 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/CocoaTransactionContextProvider.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/CocoaTransactionContextProvider.kt @@ -18,5 +18,5 @@ internal class CocoaTransactionContextProvider(cocoaTransactionContext: CocoaTra override val spanId: SpanId = SpanId(cocoaTransactionContext.spanId.toString()) override val parentSpanId: SpanId? = cocoaTransactionContext.parentSpanId?.let { SpanId(it.toString()) } - override val description: String? = cocoaTransactionContext.description + override val description: String? = cocoaTransactionContext.spanDescription } \ No newline at end of file diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt index 32839f53..0e9a8fdb 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt @@ -69,14 +69,14 @@ internal actual object SentryBridge { return CocoaSpanProvider(cocoaSpan) } - actual fun startTransaction(transactionContext: TransactionContext): Span { - val cocoaTransaction = SentrySDK.startTransactionWithContext(transactionContext.toCocoa()) - return CocoaSpanProvider(cocoaTransaction) + actual fun startTransaction(name: String, operation: String, bindToScope: Boolean): Span { + val cocoaSpan = SentrySDK.startTransactionWithName(name, operation, bindToScope) + return CocoaSpanProvider(cocoaSpan) } - actual fun startTransaction(transactionContext: TransactionContext, customSamplingContext: CustomSamplingContext): Span { - val cocoaTransaction = SentrySDK.startTransactionWithContext(transactionContext.toCocoa(), customSamplingContext.data as Map) - return CocoaSpanProvider(cocoaTransaction) + actual fun getSpan(): Span? { + val cocoaSpan = SentrySDK.span + return cocoaSpan?.let { CocoaSpanProvider(it) } } actual fun close() { diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.kt index a61144b4..990a28eb 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.kt @@ -6,11 +6,10 @@ import io.sentry.kotlin.multiplatform.BuildKonfig import io.sentry.kotlin.multiplatform.CocoaSentryEvent import io.sentry.kotlin.multiplatform.CocoaSentryOptions import io.sentry.kotlin.multiplatform.CocoaTransactionContextProvider -import io.sentry.kotlin.multiplatform.CustomSamplingContext import io.sentry.kotlin.multiplatform.SamplingContext import io.sentry.kotlin.multiplatform.SentryEvent import io.sentry.kotlin.multiplatform.SentryOptions -import io.sentry.kotlin.multiplatform.TransactionContextProv +import io.sentry.kotlin.multiplatform.TransactionContextAdapter import io.sentry.kotlin.multiplatform.nsexception.dropKotlinCrashEvent import kotlinx.cinterop.convert import platform.Foundation.NSNumber @@ -78,15 +77,10 @@ internal fun CocoaSentryOptions.applyCocoaBaseOptions(options: SentryOptions) { } tracesSampler = { - it?.let { - val cocoaTransactionContext = CocoaTransactionContextProvider(it.transactionContext) - val transactionContext = TransactionContextProv(cocoaTransactionContext) - val customSamplingContext: CustomSamplingContext? = - it.customSamplingContext?.values?.let { customSamplingContext -> - val data = customSamplingContext as? Map - data?.let { unwrappedData -> CustomSamplingContext(unwrappedData) } - } - val samplingContext = SamplingContext(transactionContext, customSamplingContext) + it?.let { context -> + val cocoaTransactionContext = CocoaTransactionContextProvider(context.transactionContext) + val transactionContext = TransactionContextAdapter(cocoaTransactionContext) + val samplingContext = SamplingContext(transactionContext) // returns null if KMP tracesSampler is null val sampleRate = options.tracesSampler?.invoke(samplingContext) sampleRate?.let { unwrappedSampleRate -> diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentrySampleDecisionExtensions.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentrySampleDecisionExtensions.kt index 099ba308..2b667690 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentrySampleDecisionExtensions.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentrySampleDecisionExtensions.kt @@ -7,7 +7,7 @@ internal fun SentrySampleDecision.toBoolean(): Boolean = when (this) { SentrySampleDecision.kSentrySampleDecisionUndecided -> false SentrySampleDecision.kSentrySampleDecisionYes -> true else -> { - false + true } } diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/TransactionContextExtensions.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/TransactionContextExtensions.kt deleted file mode 100644 index 5311010c..00000000 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/TransactionContextExtensions.kt +++ /dev/null @@ -1,19 +0,0 @@ -package io.sentry.kotlin.multiplatform.extensions - -import io.sentry.kotlin.multiplatform.CocoaSampleDecision -import io.sentry.kotlin.multiplatform.CocoaSentryId -import io.sentry.kotlin.multiplatform.CocoaSpanId -import io.sentry.kotlin.multiplatform.CocoaTransactionContext -import io.sentry.kotlin.multiplatform.TransactionContext -import kotlinx.cinterop.UnsafeNumber - -@OptIn(UnsafeNumber::class) -internal fun TransactionContext.toCocoa() = CocoaTransactionContext( - name = name, - operation = operation, - traceId = CocoaSentryId(traceId.toString()), - spanId = CocoaSpanId(spanId.toString()), - parentSpanId = parentSpanId?.let { CocoaSpanId(it.toString()) }, - parentSampled = parentSampled?.toSampleDecision() - ?: CocoaSampleDecision.kSentrySampleDecisionNo, -) diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/TransactionNameSourceExtensions.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/TransactionNameSourceExtensions.kt index 01496c71..94ecd3b3 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/TransactionNameSourceExtensions.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/TransactionNameSourceExtensions.kt @@ -29,16 +29,4 @@ internal fun NSInteger.toKmpTransactionNameSource(): TransactionNameSource { else -> TransactionNameSource.CUSTOM } return transactionNameSource -} - -internal fun TransactionNameSource.toNSInteger(): NSInteger { - val transactionNameSource = when (this) { - TransactionNameSource.CUSTOM -> 0 - TransactionNameSource.URL -> 1 - TransactionNameSource.ROUTE -> 2 - TransactionNameSource.VIEW -> 3 - TransactionNameSource.COMPONENT -> 4 - TransactionNameSource.TASK -> 5 - } - return transactionNameSource -} +} \ No newline at end of file diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/JvmTransactionContextProvider.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/JvmTransactionContextProvider.kt index 4477ce43..786b0461 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/JvmTransactionContextProvider.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/JvmTransactionContextProvider.kt @@ -10,8 +10,8 @@ internal class JvmTransactionContextProvider(jvmTransactionContext: JvmTransacti override val name: String = jvmTransactionContext.name override val transactionNameSource: TransactionNameSource = jvmTransactionContext.transactionNameSource.toKmp() - override val sampled: Boolean? = jvmTransactionContext.sampled - override val parentSampled: Boolean? = jvmTransactionContext.parentSampled + override val sampled: Boolean = jvmTransactionContext.sampled ?: false + override val parentSampled: Boolean = jvmTransactionContext.parentSampled ?: false override val operation: String = jvmTransactionContext.operation override val traceId: SentryId = SentryId(jvmTransactionContext.traceId.toString()) override val spanId: SpanId = SpanId(jvmTransactionContext.spanId.toString()) diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt index cb1bfd2f..790f41a6 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt @@ -62,14 +62,14 @@ internal actual object SentryBridge { return JvmSpanProvider(jvmTransaction) } - actual fun startTransaction(transactionContext: TransactionContext): Span { - val jvmTransaction = Sentry.startTransaction(transactionContext.toJvmTransactionContext()) + actual fun startTransaction(name: String, operation: String, bindToScope: Boolean): Span { + val jvmTransaction = Sentry.startTransaction(name, operation, bindToScope) return JvmSpanProvider(jvmTransaction) } - actual fun startTransaction(transactionContext: TransactionContext, customSamplingContext: CustomSamplingContext): Span { - val jvmTransaction = Sentry.startTransaction(transactionContext.toJvmTransactionContext(), customSamplingContext.toJvmCustomSamplingContext()) - return JvmSpanProvider(jvmTransaction) + actual fun getSpan(): Span? { + val jvmSpan = Sentry.getSpan() + return jvmSpan?.let { JvmSpanProvider(it) } } actual fun close() { diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.kt index 82aef108..da83aa8b 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.kt @@ -1,13 +1,12 @@ package io.sentry.kotlin.multiplatform.extensions import io.sentry.kotlin.multiplatform.BuildKonfig -import io.sentry.kotlin.multiplatform.CustomSamplingContext import io.sentry.kotlin.multiplatform.JvmSentryOptions import io.sentry.kotlin.multiplatform.JvmTransactionContextProvider import io.sentry.kotlin.multiplatform.SamplingContext import io.sentry.kotlin.multiplatform.SentryEvent import io.sentry.kotlin.multiplatform.SentryOptions -import io.sentry.kotlin.multiplatform.TransactionContextProv +import io.sentry.kotlin.multiplatform.TransactionContextAdapter internal fun SentryOptions.toJvmSentryOptionsCallback(): (JvmSentryOptions) -> Unit = { it.applyJvmBaseOptions(this) @@ -58,14 +57,10 @@ internal fun JvmSentryOptions.applyJvmBaseOptions(options: SentryOptions) { } } } - setTracesSampler { - val jvmTransactionContext = JvmTransactionContextProvider(it.transactionContext) - val transactionContext = TransactionContextProv(jvmTransactionContext) - val customSamplingContext: CustomSamplingContext? = - it.customSamplingContext?.data?.let { customSamplingContext -> - CustomSamplingContext(customSamplingContext) - } - val samplingContext = SamplingContext(transactionContext, customSamplingContext) + setTracesSampler { jvmSamplingContext -> + val jvmTransactionContext = JvmTransactionContextProvider(jvmSamplingContext.transactionContext) + val transactionContext = TransactionContextAdapter(jvmTransactionContext) + val samplingContext = SamplingContext(transactionContext) // returns null if KMP tracesSampler is null val sampleRate = options.tracesSampler?.invoke(samplingContext) sampleRate diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/CustomSamplingContext.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/CustomSamplingContext.kt deleted file mode 100644 index 21631388..00000000 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/CustomSamplingContext.kt +++ /dev/null @@ -1,5 +0,0 @@ -package io.sentry.kotlin.multiplatform - -public data class CustomSamplingContext( - public val data: Map = mapOf() -) \ No newline at end of file diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SamplingContext.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SamplingContext.kt index 3c8acba8..8d465bbd 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SamplingContext.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SamplingContext.kt @@ -2,5 +2,4 @@ package io.sentry.kotlin.multiplatform public data class SamplingContext( public val transactionContext: TransactionContext, - public val customSamplingContext: CustomSamplingContext? ) diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt index a2b42dc5..611190da 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt @@ -29,9 +29,9 @@ internal expect object SentryBridge { fun startTransaction(name: String, operation: String): Span - fun startTransaction(transactionContext: TransactionContext): Span + fun startTransaction(name: String, operation: String, bindToScope: Boolean): Span - fun startTransaction(transactionContext: TransactionContext, customSamplingContext: CustomSamplingContext): Span + fun getSpan(): Span? fun close() } diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryKMP.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryKMP.kt index 2c8d7787..3dd76618 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryKMP.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryKMP.kt @@ -117,14 +117,39 @@ public object Sentry { SentryBridge.setUser(user) } + /** + * Starts a new transaction and returns a new `Span` representing it. The `Span` can be + * used to record additional information about the transaction or add child spans. + * + * @param name The name of the transaction. + * @param operation The operation of the transaction, typically the name of the function or endpoint. + * @return A new `Span` representing the transaction. + */ public fun startTransaction(name: String, operation: String): Span { return SentryBridge.startTransaction(name, operation) } - public fun startTransaction(name: String, operation: String, description: String): Span { - return SentryBridge.startTransaction(name, operation) + /** + * Starts a new transaction and returns a new `Span` representing it. The `Span` can be + * used to record additional information about the transaction or add child spans. + * + * @param name The name of the transaction. + * @param operation The operation of the transaction, typically the name of the function or endpoint. + * @param bindToScope Whether to bind the transaction to the current scope. + * @return A new `Span` representing the transaction. + */ + public fun startTransaction(name: String, operation: String, bindToScope: Boolean): Span { + return SentryBridge.startTransaction(name, operation, bindToScope) } + /** + * Apple: returns the active root transaction + * + * JVM: returns the active transaction or the latest active child span + */ + public fun getSpan(): Span? { + return SentryBridge.getSpan() + } /** * Throws a RuntimeException, useful for testing. diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SpanContext.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SpanContext.kt index 2106b98a..59230609 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SpanContext.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SpanContext.kt @@ -20,5 +20,5 @@ public interface SpanContext { public val spanId: SpanId public val parentSpanId: SpanId? public val description: String? - public val sampled: Boolean? + public val sampled: Boolean } diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContext.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContext.kt index 41505d3e..93001c4a 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContext.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContext.kt @@ -2,11 +2,11 @@ package io.sentry.kotlin.multiplatform import io.sentry.kotlin.multiplatform.protocol.TransactionNameSource -public class TransactionContextProv constructor(private val transactionContext: TransactionContext) : +public class TransactionContextAdapter constructor(private val transactionContext: TransactionContext) : TransactionContext by transactionContext public interface TransactionContext : SpanContext { public val name: String public val transactionNameSource: TransactionNameSource - public val parentSampled: Boolean? + public val parentSampled: Boolean } \ No newline at end of file diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/CustomInstrumentationIntegrationTest.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/CustomInstrumentationIntegrationTest.kt deleted file mode 100644 index 410315ff..00000000 --- a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/CustomInstrumentationIntegrationTest.kt +++ /dev/null @@ -1,5 +0,0 @@ -package io.sentry.kotlin.multiplatform - -class CustomInstrumentationIntegrationTest : BaseSentryTest() { - -} \ No newline at end of file diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TracesSamplerRateTest.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TracesSamplerRateTest.kt index ec2624a0..2d89d253 100644 --- a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TracesSamplerRateTest.kt +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TracesSamplerRateTest.kt @@ -3,7 +3,6 @@ package io.sentry.kotlin.multiplatform import io.sentry.kotlin.multiplatform.protocol.SentryId import io.sentry.kotlin.multiplatform.protocol.SpanId import io.sentry.kotlin.multiplatform.protocol.TransactionNameSource -import io.sentry.kotlin.multiplatform.utils.createMockCustomSamplingContext import io.sentry.kotlin.multiplatform.utils.createMockTransactionContext import kotlin.test.BeforeTest import kotlin.test.Test @@ -15,20 +14,18 @@ class MockTransactionContext( override val spanId: SpanId, override val parentSpanId: SpanId?, override val description: String?, - override val sampled: Boolean?, + override val sampled: Boolean, override val name: String, override val transactionNameSource: TransactionNameSource, - override val parentSampled: Boolean? + override val parentSampled: Boolean ) : TransactionContext class TracesSamplerRateTest { private lateinit var mockTransactionContext: TransactionContext - private lateinit var mockCustomSamplingContext: CustomSamplingContext @BeforeTest fun setup() { mockTransactionContext = createMockTransactionContext() - mockCustomSamplingContext = createMockCustomSamplingContext() } @Test @@ -39,7 +36,6 @@ class TracesSamplerRateTest { } val samplingContext = SamplingContext( transactionContext = mockTransactionContext, - customSamplingContext = mockCustomSamplingContext ) val sampleRate = options.tracesSampler?.invoke(samplingContext) assertEquals(null, sampleRate) @@ -53,7 +49,6 @@ class TracesSamplerRateTest { } val samplingContext = SamplingContext( transactionContext = mockTransactionContext, - customSamplingContext = mockCustomSamplingContext ) val sampleRate = options.tracesSampler?.invoke(samplingContext) assertEquals(0.5, sampleRate) @@ -73,7 +68,6 @@ class TracesSamplerRateTest { // Assert that the sample rate is 0.5 val samplingContext = SamplingContext( transactionContext = mockTransactionContext, - customSamplingContext = mockCustomSamplingContext ) val sampleRate = options.tracesSampler?.invoke(samplingContext) assertEquals(0.5, sampleRate) @@ -81,7 +75,6 @@ class TracesSamplerRateTest { // Assert that the sample rate is 0.1 val differentSamplingContext = SamplingContext( transactionContext = createMockTransactionContext(name = "different"), - customSamplingContext = mockCustomSamplingContext ) val differentSampleRate = options.tracesSampler?.invoke(differentSamplingContext) assertEquals(0.1, differentSampleRate) @@ -99,7 +92,6 @@ class TracesSamplerRateTest { val samplingContext = SamplingContext( transactionContext = mockTransactionContext, - customSamplingContext = mockCustomSamplingContext ) options.tracesSampler?.invoke(samplingContext) assertEquals(expectedName, actualName) @@ -117,7 +109,6 @@ class TracesSamplerRateTest { val samplingContext = SamplingContext( transactionContext = mockTransactionContext, - customSamplingContext = mockCustomSamplingContext ) options.tracesSampler?.invoke(samplingContext) assertEquals(expectedSpanId, actualSpanId) @@ -135,7 +126,6 @@ class TracesSamplerRateTest { val samplingContext = SamplingContext( transactionContext = mockTransactionContext, - customSamplingContext = mockCustomSamplingContext ) options.tracesSampler?.invoke(samplingContext) assertEquals(expectedParentSpanId, actualParentSpanId) @@ -153,7 +143,6 @@ class TracesSamplerRateTest { val samplingContext = SamplingContext( transactionContext = mockTransactionContext, - customSamplingContext = mockCustomSamplingContext ) options.tracesSampler?.invoke(samplingContext) assertEquals(expectedDescription, actualDescription) @@ -171,7 +160,6 @@ class TracesSamplerRateTest { val samplingContext = SamplingContext( transactionContext = mockTransactionContext, - customSamplingContext = mockCustomSamplingContext ) options.tracesSampler?.invoke(samplingContext) assertEquals(expectedSampled, actualSampled) @@ -189,7 +177,6 @@ class TracesSamplerRateTest { val samplingContext = SamplingContext( transactionContext = mockTransactionContext, - customSamplingContext = mockCustomSamplingContext ) options.tracesSampler?.invoke(samplingContext) assertEquals(expectedParentSampled, actualParentSampled) @@ -207,7 +194,6 @@ class TracesSamplerRateTest { val samplingContext = SamplingContext( transactionContext = mockTransactionContext, - customSamplingContext = mockCustomSamplingContext ) options.tracesSampler?.invoke(samplingContext) assertEquals(expectedOperation, actualOperation) @@ -225,27 +211,8 @@ class TracesSamplerRateTest { val samplingContext = SamplingContext( transactionContext = mockTransactionContext, - customSamplingContext = mockCustomSamplingContext ) options.tracesSampler?.invoke(samplingContext) assertEquals(expectedTransactionNameSource, actualTransactionNameSource) } - - @Test - fun `tracerSampler returns correct CustomSamplingContext`() { - val options = SentryOptions() - val expectedData = mockCustomSamplingContext.data - var actualData: Map? = null - options.tracesSampler = { - actualData = it.customSamplingContext?.data - null - } - - val samplingContext = SamplingContext( - transactionContext = mockTransactionContext, - customSamplingContext = mockCustomSamplingContext, - ) - options.tracesSampler?.invoke(samplingContext) - assertEquals(expectedData, actualData) - } -} \ No newline at end of file +} diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TracesSamplerRateIntegrationTest.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TransactionIntegrationTest.kt similarity index 61% rename from sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TracesSamplerRateIntegrationTest.kt rename to sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TransactionIntegrationTest.kt index ff47ffdc..71158f83 100644 --- a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TracesSamplerRateIntegrationTest.kt +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TransactionIntegrationTest.kt @@ -4,7 +4,7 @@ import io.sentry.kotlin.multiplatform.utils.fakeDsn import kotlin.test.Test import kotlin.test.assertEquals -class TracesSamplerRateIntegrationTest: BaseSentryTest() { +class TransactionIntegrationTest: BaseSentryTest() { @Test fun `tracesSampler can receive correct TransactionContext name`() { @@ -38,35 +38,54 @@ class TracesSamplerRateIntegrationTest: BaseSentryTest() { } @Test - fun `tracesSampler can receive correct TransactionContext parentSpanId`() { - var actualParentSpanId = "" + fun `parentSpanId is correct after starting child span`() { sentryInit { it.dsn = fakeDsn - it.tracesSampler = { context -> - actualParentSpanId = context.transactionContext.parentSpanId.toString() - null - } } val transaction = Sentry.startTransaction("test", "testOperation") + val child = transaction.startChild("child") + child.finish() transaction.finish() - assertEquals(transaction.parentSpanId?.toString(), actualParentSpanId) + assertEquals(child.parentSpanId?.toString(), transaction.spanId.toString()) } @Test - fun `tracesSampler can receive correct TransactionContext description`() { - val expectedDescription = "test" - var actualDescription: String? = "" + fun `getSpan returns the current active span with bindToScope enabled`() { sentryInit { it.dsn = fakeDsn - it.tracesSampler = { context -> - actualDescription = context.transactionContext.description - null - } } - val transaction = Sentry.startTransaction("test", "testOperation") - transaction.description = expectedDescription + val transaction = Sentry.startTransaction("test", "testOperation", bindToScope = true) + val activeTransactionSpanId = Sentry.getSpan()?.spanId + transaction.finish() + assertEquals(activeTransactionSpanId, transaction.spanId, "activeTransactionSpanId should be equal to transaction.spanId") + } + + @Test + fun `getSpan returns null when bindToScope is disabled`() { + sentryInit { + it.dsn = fakeDsn + } + val transaction = Sentry.startTransaction("test", "testOperation", bindToScope = false) + val activeTransactionSpanId = Sentry.getSpan()?.spanId + val child = transaction.startChild("child") + val activeChildSpanId = Sentry.getSpan()?.spanId + child.finish() + transaction.finish() + assertEquals(activeTransactionSpanId, null) + assertEquals(activeChildSpanId, null) + } + + @Test + fun `getSpan returns null when Transaction has finished`() { + sentryInit { + it.dsn = fakeDsn + } + val transaction = Sentry.startTransaction("test", "testOperation", bindToScope = true) + val activeTransactionSpanId = Sentry.getSpan()?.spanId transaction.finish() - assertEquals(expectedDescription, actualDescription) + val activeTransactionSpanIdAfterFinish = Sentry.getSpan()?.spanId + assertEquals(activeTransactionSpanId, transaction.spanId) + assertEquals(activeTransactionSpanIdAfterFinish, null) } @Test @@ -87,8 +106,8 @@ class TracesSamplerRateIntegrationTest: BaseSentryTest() { @Test fun `tracesSampler can receive correct TransactionContext sampled`() { - val expectedSampled = null - var actualSampled: Boolean? = false + val expectedSampled = false + var actualSampled: Boolean? = null sentryInit { it.dsn = fakeDsn it.tracesSampler = { context -> @@ -103,8 +122,8 @@ class TracesSamplerRateIntegrationTest: BaseSentryTest() { @Test fun `tracesSampler can receive correct TransactionContext parentSampled`() { - val expectedSampled = null - var actualSampled: Boolean? = false + val expectedSampled = false + var actualSampled: Boolean? = null sentryInit { it.dsn = fakeDsn it.tracesSampler = { context -> diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/utils/MockSamplingContextFactory.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/utils/MockSamplingContextFactory.kt index 7b0e182b..ac488a3b 100644 --- a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/utils/MockSamplingContextFactory.kt +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/utils/MockSamplingContextFactory.kt @@ -1,6 +1,5 @@ package io.sentry.kotlin.multiplatform.utils -import io.sentry.kotlin.multiplatform.CustomSamplingContext import io.sentry.kotlin.multiplatform.MockTransactionContext import io.sentry.kotlin.multiplatform.TransactionContext import io.sentry.kotlin.multiplatform.protocol.SentryId @@ -13,10 +12,10 @@ fun createMockTransactionContext( spanId: SpanId = SpanId.EMPTY_ID, parentSpanId: SpanId? = SpanId("123"), description: String? = "test description", - sampled: Boolean? = null, + sampled: Boolean = false, name: String = "test", transactionNameSource: TransactionNameSource = TransactionNameSource.TASK, - parentSampled: Boolean? = null + parentSampled: Boolean = false ): TransactionContext { return MockTransactionContext( operation = operation, @@ -30,7 +29,3 @@ fun createMockTransactionContext( parentSampled = parentSampled ) } - -fun createMockCustomSamplingContext(data: Map = mapOf("test" to "test")): CustomSamplingContext { - return CustomSamplingContext(data) -} \ No newline at end of file diff --git a/sentry-samples/kmp-app-cocoapods/shared/src/commonMain/kotlin/sample.kmp.app/LoginImpl.kt b/sentry-samples/kmp-app-cocoapods/shared/src/commonMain/kotlin/sample.kmp.app/LoginImpl.kt index fddd8726..19a837d3 100644 --- a/sentry-samples/kmp-app-cocoapods/shared/src/commonMain/kotlin/sample.kmp.app/LoginImpl.kt +++ b/sentry-samples/kmp-app-cocoapods/shared/src/commonMain/kotlin/sample.kmp.app/LoginImpl.kt @@ -15,6 +15,7 @@ object LoginImpl { * */ fun login(username: String? = null) { + val transaction = Sentry.startTransaction("Authentication", "login", bindToScope = true) try { validateUsername(username) } catch (exception: InvalidUsernameException) { @@ -39,6 +40,8 @@ object LoginImpl { Sentry.captureUserFeedback(userFeedback) } catch (exception: IllegalArgumentException) { throw exception + } finally { + transaction.finish() } } diff --git a/sentry-samples/kmp-app-cocoapods/shared/src/commonMain/kotlin/sample.kmp.app/SentrySetup.kt b/sentry-samples/kmp-app-cocoapods/shared/src/commonMain/kotlin/sample.kmp.app/SentrySetup.kt index 63bbd8b5..5eca64fe 100644 --- a/sentry-samples/kmp-app-cocoapods/shared/src/commonMain/kotlin/sample.kmp.app/SentrySetup.kt +++ b/sentry-samples/kmp-app-cocoapods/shared/src/commonMain/kotlin/sample.kmp.app/SentrySetup.kt @@ -74,5 +74,6 @@ private fun optionsConfiguration(): OptionsConfiguration { event } } + it.tracesSampleRate = 1.0 } } diff --git a/sentry-samples/kmp-app-mvvm-di/shared/src/commonMain/kotlin/sentry.kmp.demo/models/AuthenticationViewModel.kt b/sentry-samples/kmp-app-mvvm-di/shared/src/commonMain/kotlin/sentry.kmp.demo/models/AuthenticationViewModel.kt index b0d3f153..2c7d9326 100644 --- a/sentry-samples/kmp-app-mvvm-di/shared/src/commonMain/kotlin/sentry.kmp.demo/models/AuthenticationViewModel.kt +++ b/sentry-samples/kmp-app-mvvm-di/shared/src/commonMain/kotlin/sentry.kmp.demo/models/AuthenticationViewModel.kt @@ -10,6 +10,7 @@ class AuthenticationViewModel : ViewModel() { fun login(withError: Boolean): Boolean { return if (withError) { + val transaction = Sentry.startTransaction("Authentication", "login", bindToScope = true) try { throw LoginException("Error logging in") } catch (exception: Exception) { @@ -23,6 +24,8 @@ class AuthenticationViewModel : ViewModel() { it.level = SentryLevel.ERROR } false + } finally { + transaction.finish() } } else { true diff --git a/sentry-samples/kmp-app-mvvm-di/shared/src/commonMain/kotlin/sentry.kmp.demo/sentry/SentrySetup.kt b/sentry-samples/kmp-app-mvvm-di/shared/src/commonMain/kotlin/sentry.kmp.demo/sentry/SentrySetup.kt index 920aa3a2..5dbae29f 100644 --- a/sentry-samples/kmp-app-mvvm-di/shared/src/commonMain/kotlin/sentry.kmp.demo/sentry/SentrySetup.kt +++ b/sentry-samples/kmp-app-mvvm-di/shared/src/commonMain/kotlin/sentry.kmp.demo/sentry/SentrySetup.kt @@ -25,6 +25,7 @@ private val optionsConfiguration: OptionsConfiguration = { breadcrumb.message = "Add message before every breadcrumb" breadcrumb } + it.tracesSampleRate = 1.0 } /** diff --git a/sentry-samples/kmp-app-spm/androidApp/src/main/java/sample/kmp/app/android/MainActivity.kt b/sentry-samples/kmp-app-spm/androidApp/src/main/java/sample/kmp/app/android/MainActivity.kt index ed05c387..b03d0d74 100644 --- a/sentry-samples/kmp-app-spm/androidApp/src/main/java/sample/kmp/app/android/MainActivity.kt +++ b/sentry-samples/kmp-app-spm/androidApp/src/main/java/sample/kmp/app/android/MainActivity.kt @@ -35,10 +35,6 @@ class MainActivity : AppCompatActivity() { captureHardCrashBtn.setOnClickListener { LoginImpl.login() } - - val transaction = Sentry.startTransaction("adsaa", "activity") - sleep(5000) - transaction.finish() } } diff --git a/sentry-samples/kmp-app-spm/shared/src/commonMain/kotlin/sample.kmp.app/LoginImpl.kt b/sentry-samples/kmp-app-spm/shared/src/commonMain/kotlin/sample.kmp.app/LoginImpl.kt index fddd8726..19a837d3 100644 --- a/sentry-samples/kmp-app-spm/shared/src/commonMain/kotlin/sample.kmp.app/LoginImpl.kt +++ b/sentry-samples/kmp-app-spm/shared/src/commonMain/kotlin/sample.kmp.app/LoginImpl.kt @@ -15,6 +15,7 @@ object LoginImpl { * */ fun login(username: String? = null) { + val transaction = Sentry.startTransaction("Authentication", "login", bindToScope = true) try { validateUsername(username) } catch (exception: InvalidUsernameException) { @@ -39,6 +40,8 @@ object LoginImpl { Sentry.captureUserFeedback(userFeedback) } catch (exception: IllegalArgumentException) { throw exception + } finally { + transaction.finish() } } diff --git a/sentry-samples/kmp-app-spm/shared/src/commonMain/kotlin/sample.kmp.app/SentrySetup.kt b/sentry-samples/kmp-app-spm/shared/src/commonMain/kotlin/sample.kmp.app/SentrySetup.kt index 7ce97e2b..7f71c0fc 100644 --- a/sentry-samples/kmp-app-spm/shared/src/commonMain/kotlin/sample.kmp.app/SentrySetup.kt +++ b/sentry-samples/kmp-app-spm/shared/src/commonMain/kotlin/sample.kmp.app/SentrySetup.kt @@ -60,18 +60,6 @@ private fun optionsConfiguration(): OptionsConfiguration { event } } - it.tracesSampler = { context -> - println("TEST: ${context.transactionContext.transactionNameSource}") - println("TEST: ${context.transactionContext.operation}") - println("TEST: ${context.transactionContext.name}") - println("TEST: ${context.transactionContext.parentSpanId}") - println("TEST: ${context.transactionContext.spanId}") - println("TEST: ${context.transactionContext.traceId}") - println("TEST: ${context.transactionContext.sampled}") - println("TEST: ${context.transactionContext.parentSampled}") - println("TEST: ${context.transactionContext.description}") - println("TEST: ${context.transactionContext.parentSpanId}") - 1.0 - } + it.tracesSampleRate = 1.0 } } From d924a226f73386fb151a8177e541e878eeb19064 Mon Sep 17 00:00:00 2001 From: buenaflor Date: Thu, 4 May 2023 17:45:25 +0200 Subject: [PATCH 11/43] adjust boolean decision --- .../multiplatform/extensions/SentrySampleDecisionExtensions.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentrySampleDecisionExtensions.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentrySampleDecisionExtensions.kt index 2b667690..099ba308 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentrySampleDecisionExtensions.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentrySampleDecisionExtensions.kt @@ -7,7 +7,7 @@ internal fun SentrySampleDecision.toBoolean(): Boolean = when (this) { SentrySampleDecision.kSentrySampleDecisionUndecided -> false SentrySampleDecision.kSentrySampleDecisionYes -> true else -> { - true + false } } From 79a82bf24445eeeae732523e85c0dd24201908bc Mon Sep 17 00:00:00 2001 From: buenaflor Date: Thu, 4 May 2023 17:46:48 +0200 Subject: [PATCH 12/43] remove unnecessary code --- .../sample/kmp/app/android/MainActivity.kt | 24 ------------------- .../kotlin/sample.kmp.app/SentrySetup.kt | 13 ---------- 2 files changed, 37 deletions(-) diff --git a/sentry-samples/kmp-app-cocoapods/androidApp/src/main/java/sample/kmp/app/android/MainActivity.kt b/sentry-samples/kmp-app-cocoapods/androidApp/src/main/java/sample/kmp/app/android/MainActivity.kt index aff0f82e..1b693381 100644 --- a/sentry-samples/kmp-app-cocoapods/androidApp/src/main/java/sample/kmp/app/android/MainActivity.kt +++ b/sentry-samples/kmp-app-cocoapods/androidApp/src/main/java/sample/kmp/app/android/MainActivity.kt @@ -7,17 +7,12 @@ import androidx.appcompat.app.AppCompatActivity import io.sentry.kotlin.multiplatform.Attachment import io.sentry.kotlin.multiplatform.Sentry import io.sentry.kotlin.multiplatform.protocol.Breadcrumb -import io.sentry.kotlin.multiplatform.withSpan -import io.sentry.kotlin.multiplatform.withTrace -import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.launch import sample.kmp.app.LoginImpl import sample.kmp.app.Platform import sample.kmp.app.configureSentryScope import sample.kmp.app.initializeSentry import java.io.FileOutputStream import java.io.IOException -import java.lang.Thread.sleep class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { @@ -39,25 +34,6 @@ class MainActivity : AppCompatActivity() { captureHardCrashBtn.setOnClickListener { LoginImpl.login() } - - GlobalScope.launch { - println(getData()) - } - val trace = Sentry.startTransaction("myTransaction", "myOp") - - } - - private suspend fun getData(): String { - return withTrace("getData", "custom") { - withSpan("getDataSpan") { - sleep(1000) - } - withSpan("getDataSpan2") { - sleep(1000) - } - sleep(5000) - "foo" - } } } diff --git a/sentry-samples/kmp-app-cocoapods/shared/src/commonMain/kotlin/sample.kmp.app/SentrySetup.kt b/sentry-samples/kmp-app-cocoapods/shared/src/commonMain/kotlin/sample.kmp.app/SentrySetup.kt index 5eca64fe..866fc4e4 100644 --- a/sentry-samples/kmp-app-cocoapods/shared/src/commonMain/kotlin/sample.kmp.app/SentrySetup.kt +++ b/sentry-samples/kmp-app-cocoapods/shared/src/commonMain/kotlin/sample.kmp.app/SentrySetup.kt @@ -26,12 +26,6 @@ fun configureSentryScope() { */ fun initializeSentry(context: Context) { Sentry.init(context, optionsConfiguration()) - val trace = Sentry.startTransaction("App Startup", "App Startup") - var i = 0 - while(i <= 1000000000) { - i += 1 - } - trace.finish() } /** @@ -41,12 +35,6 @@ fun initializeSentry(context: Context) { */ fun initializeSentry() { Sentry.init(optionsConfiguration()) - val trace = Sentry.startTransaction("App Startup", "App Startup") - var i = 0 - while(i <= 1000000) { - i += 1 - } - trace.finish() } /** Returns a shared options configuration */ @@ -70,7 +58,6 @@ private fun optionsConfiguration(): OptionsConfiguration { if (event.environment == "test") { null } else { - println("HAHA: ${event.exceptions}") event } } From 539d6bf7baff6f796390a6346cd93222a3d9383a Mon Sep 17 00:00:00 2001 From: buenaflor Date: Thu, 4 May 2023 17:49:07 +0200 Subject: [PATCH 13/43] change doc of SpanContexT --- .../kotlin/multiplatform/SpanContext.kt | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SpanContext.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SpanContext.kt index 59230609..c2419c5a 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SpanContext.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SpanContext.kt @@ -3,22 +3,24 @@ package io.sentry.kotlin.multiplatform import io.sentry.kotlin.multiplatform.protocol.SentryId import io.sentry.kotlin.multiplatform.protocol.SpanId -/** - * An interface representing the context of a span. - * - * @property operation The name of the operation associated with the span. - * @property traceId Determines which trace the span belongs to. - * @property spanId The unique identifier of the span. - * @property parentSpanId The unique identifier of the span's parent, if any. - * @property description A longer description of the span's operation, which uniquely identifies the span but is - * consistent across instances of the span. - * @property sampled Indicates if the span is sampled. - */ +/** An interface representing the context of a span. */ public interface SpanContext { + /** The name of the operation associated with the span.*/ public val operation: String + + /** Determines which trace the span belongs to.*/ public val traceId: SentryId + + /** The unique identifier of the span.*/ public val spanId: SpanId + + /** The unique identifier of the span's parent, if any.*/ public val parentSpanId: SpanId? + + /** A longer description of the span's operation, which uniquely identifies the span but is + * consistent across instances of the span.*/ public val description: String? + + /** Indicates if the span is sampled.*/ public val sampled: Boolean } From a21eb1740f040eff63b4c66f3c1d3075069d8930 Mon Sep 17 00:00:00 2001 From: GIancarlo Buenaflor Date: Thu, 23 Nov 2023 11:52:32 +0100 Subject: [PATCH 14/43] Update providers --- .../{CocoaScopeProvider.kt => ScopeProvider.apple.kt} | 3 +-- .../sentry/kotlin/multiplatform/SentryBridge.apple.kt | 11 ++++------- .../{CocoaSpanProvider.kt => SpanProvider.apple.kt} | 6 +++--- ...rovider.kt => TransactionContextProvider.apple.kt} | 2 +- .../extensions/SentryOptionsExtensions.apple.kt | 4 ++-- ...tusExtensions.kt => SpanStatusExtensions.apple.kt} | 1 - ...ns.kt => TransactionNameSourceExtensions.apple.kt} | 1 - .../kotlin/multiplatform/BaseSentryScopeTest.kt | 2 +- .../{JvmScopeProvider.kt => ScopeProvider.jvm.kt} | 3 +-- .../sentry/kotlin/multiplatform/SentryBridge.jvm.kt | 8 ++++---- .../{JvmSpanProvider.kt => SpanProvider.jvm.kt} | 6 +++--- ...tProvider.kt => TransactionContextProvider.jvm.kt} | 2 +- .../extensions/SentryOptionsExtensions.jvm.kt | 4 ++-- ...ions.kt => TransactionNameSourceExtensions.jvm.kt} | 0 .../kotlin/multiplatform/BaseSentryScopeTest.kt | 2 +- .../sentry/kotlin/multiplatform/TransactionContext.kt | 9 +++++---- .../kotlin/multiplatform/TracesSamplerRateTest.kt | 8 ++++---- .../multiplatform/TransactionIntegrationTest.kt | 1 - .../multiplatform/utils/MockSamplingContextFactory.kt | 6 +++--- .../kmp-app-cocoapods/androidApp/build.gradle.kts | 2 +- 20 files changed, 37 insertions(+), 44 deletions(-) rename sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/{CocoaScopeProvider.kt => ScopeProvider.apple.kt} (98%) rename sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/{CocoaSpanProvider.kt => SpanProvider.apple.kt} (91%) rename sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/{CocoaTransactionContextProvider.kt => TransactionContextProvider.apple.kt} (92%) rename sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/{SpanStatusExtensions.kt => SpanStatusExtensions.apple.kt} (98%) rename sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/{TransactionNameSourceExtensions.kt => TransactionNameSourceExtensions.apple.kt} (99%) rename sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/{JvmScopeProvider.kt => ScopeProvider.jvm.kt} (97%) rename sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/{JvmSpanProvider.kt => SpanProvider.jvm.kt} (92%) rename sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/{JvmTransactionContextProvider.kt => TransactionContextProvider.jvm.kt} (92%) rename sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/{TransactionNameSourceExtensions.kt => TransactionNameSourceExtensions.jvm.kt} (100%) diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/CocoaScopeProvider.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/ScopeProvider.apple.kt similarity index 98% rename from sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/CocoaScopeProvider.kt rename to sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/ScopeProvider.apple.kt index f7906086..f071ad2f 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/CocoaScopeProvider.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/ScopeProvider.apple.kt @@ -10,8 +10,7 @@ import io.sentry.kotlin.multiplatform.protocol.Breadcrumb import io.sentry.kotlin.multiplatform.protocol.User import Scope.Sentry.SentryScope as PrivateCocoaScope -internal class CocoaScopeProvider(private val scope: CocoaScope) : Scope { - +internal class ScopeProvider(private val scope: CocoaScope) : Scope { /* This bridge exposes private Cocoa SDK API to fetch internal properties such as user, level, etc. We need this in order to return properties because the Cocoa SDK doesn't implement getters. diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.apple.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.apple.kt index ba94a008..e7049379 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.apple.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.apple.kt @@ -1,8 +1,6 @@ package io.sentry.kotlin.multiplatform import cocoapods.Sentry.SentrySDK -import cocoapods.Sentry.SentrySpanProtocol -import io.sentry.kotlin.multiplatform.extensions.toCocoa import io.sentry.kotlin.multiplatform.extensions.toCocoaBreadcrumb import io.sentry.kotlin.multiplatform.extensions.toCocoaUser import io.sentry.kotlin.multiplatform.extensions.toCocoaUserFeedback @@ -19,7 +17,6 @@ public actual abstract class Context internal expect fun initSentry(configuration: OptionsConfiguration) internal actual object SentryBridge { - actual fun init(context: Context, configuration: OptionsConfiguration) { initSentry(configuration) } @@ -69,17 +66,17 @@ internal actual object SentryBridge { actual fun startTransaction(name: String, operation: String): Span { val cocoaSpan = SentrySDK.startTransactionWithName(name, operation) - return CocoaSpanProvider(cocoaSpan) + return SpanProvider(cocoaSpan) } actual fun startTransaction(name: String, operation: String, bindToScope: Boolean): Span { val cocoaSpan = SentrySDK.startTransactionWithName(name, operation, bindToScope) - return CocoaSpanProvider(cocoaSpan) + return SpanProvider(cocoaSpan) } actual fun getSpan(): Span? { val cocoaSpan = SentrySDK.span - return cocoaSpan?.let { CocoaSpanProvider(it) } + return cocoaSpan?.let { SpanProvider(it) } } actual fun close() { @@ -89,7 +86,7 @@ internal actual object SentryBridge { private fun configureScopeCallback(scopeCallback: ScopeCallback): (CocoaScope?) -> Unit { return { cocoaScope -> val cocoaScopeProvider = cocoaScope?.let { - CocoaScopeProvider(it) + ScopeProvider(it) } cocoaScopeProvider?.let { scopeCallback.invoke(it) diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/CocoaSpanProvider.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SpanProvider.apple.kt similarity index 91% rename from sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/CocoaSpanProvider.kt rename to sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SpanProvider.apple.kt index 11306778..e98c8206 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/CocoaSpanProvider.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SpanProvider.apple.kt @@ -5,16 +5,16 @@ import io.sentry.kotlin.multiplatform.extensions.toCocoa import io.sentry.kotlin.multiplatform.extensions.toKmp import io.sentry.kotlin.multiplatform.protocol.SpanId -internal class CocoaSpanProvider(private val cocoaSpan: SentrySpanProtocol) : Span { +internal class SpanProvider(private val cocoaSpan: SentrySpanProtocol) : Span { override fun startChild(operation: String): Span { val cocoaSpan = cocoaSpan.startChildWithOperation(operation) - return CocoaSpanProvider(cocoaSpan) + return SpanProvider(cocoaSpan) } override fun startChild(operation: String, description: String?): Span { val cocoaSpan = cocoaSpan.startChildWithOperation(operation = operation, description = description) - return CocoaSpanProvider(cocoaSpan) + return SpanProvider(cocoaSpan) } override fun finish() { diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/CocoaTransactionContextProvider.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContextProvider.apple.kt similarity index 92% rename from sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/CocoaTransactionContextProvider.kt rename to sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContextProvider.apple.kt index 6990f999..300f1856 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/CocoaTransactionContextProvider.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContextProvider.apple.kt @@ -6,7 +6,7 @@ import io.sentry.kotlin.multiplatform.protocol.SentryId import io.sentry.kotlin.multiplatform.protocol.SpanId import io.sentry.kotlin.multiplatform.protocol.TransactionNameSource -internal class CocoaTransactionContextProvider(cocoaTransactionContext: CocoaTransactionContext) : +internal class TransactionContextProvider(cocoaTransactionContext: CocoaTransactionContext) : TransactionContext { override val name: String = cocoaTransactionContext.name override val transactionNameSource: TransactionNameSource = diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.apple.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.apple.kt index 91d7384d..efe91abd 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.apple.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.apple.kt @@ -5,7 +5,7 @@ import cocoapods.Sentry.SentryHttpStatusCodeRange import io.sentry.kotlin.multiplatform.BuildKonfig import io.sentry.kotlin.multiplatform.CocoaSentryEvent import io.sentry.kotlin.multiplatform.CocoaSentryOptions -import io.sentry.kotlin.multiplatform.CocoaTransactionContextProvider +import io.sentry.kotlin.multiplatform.TransactionContextProvider import io.sentry.kotlin.multiplatform.SamplingContext import io.sentry.kotlin.multiplatform.SentryEvent import io.sentry.kotlin.multiplatform.SentryOptions @@ -89,7 +89,7 @@ internal fun CocoaSentryOptions.applyCocoaBaseOptions(options: SentryOptions) { tracesSampler = { it?.let { context -> val cocoaTransactionContext = - CocoaTransactionContextProvider(context.transactionContext) + TransactionContextProvider(context.transactionContext) val transactionContext = TransactionContextAdapter(cocoaTransactionContext) val samplingContext = SamplingContext(transactionContext) // returns null if KMP tracesSampler is null diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SpanStatusExtensions.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SpanStatusExtensions.apple.kt similarity index 98% rename from sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SpanStatusExtensions.kt rename to sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SpanStatusExtensions.apple.kt index b6c3dba6..d42601cd 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SpanStatusExtensions.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SpanStatusExtensions.apple.kt @@ -1,6 +1,5 @@ package io.sentry.kotlin.multiplatform.extensions -import cocoapods.Sentry.SentrySpanStatus import io.sentry.kotlin.multiplatform.CocoaSpanStatus import io.sentry.kotlin.multiplatform.SpanStatus diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/TransactionNameSourceExtensions.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/TransactionNameSourceExtensions.apple.kt similarity index 99% rename from sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/TransactionNameSourceExtensions.kt rename to sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/TransactionNameSourceExtensions.apple.kt index 94ecd3b3..9c24b3cf 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/TransactionNameSourceExtensions.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/TransactionNameSourceExtensions.apple.kt @@ -16,7 +16,6 @@ typedef NS_ENUM(NSInteger, SentryTransactionNameSource) { kSentryTransactionNameSourceTask }; */ - @OptIn(UnsafeNumber::class) internal fun NSInteger.toKmpTransactionNameSource(): TransactionNameSource { val transactionNameSource = when (this.toInt()) { diff --git a/sentry-kotlin-multiplatform/src/commonAppleTest/kotlin/io/sentry/kotlin/multiplatform/BaseSentryScopeTest.kt b/sentry-kotlin-multiplatform/src/commonAppleTest/kotlin/io/sentry/kotlin/multiplatform/BaseSentryScopeTest.kt index bb9aac47..9efd2cda 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleTest/kotlin/io/sentry/kotlin/multiplatform/BaseSentryScopeTest.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleTest/kotlin/io/sentry/kotlin/multiplatform/BaseSentryScopeTest.kt @@ -5,6 +5,6 @@ import cocoapods.Sentry.SentryScope as CocoaScope actual abstract class BaseSentryScopeTest { actual fun initializeScope(): Scope { val cocoaScope = CocoaScope() - return CocoaScopeProvider(cocoaScope) + return `ScopeProvider.apple`(cocoaScope) } } diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/JvmScopeProvider.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/ScopeProvider.jvm.kt similarity index 97% rename from sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/JvmScopeProvider.kt rename to sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/ScopeProvider.jvm.kt index 8f32b633..27d02e3f 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/JvmScopeProvider.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/ScopeProvider.jvm.kt @@ -8,8 +8,7 @@ import io.sentry.kotlin.multiplatform.extensions.toKmpUser import io.sentry.kotlin.multiplatform.protocol.Breadcrumb import io.sentry.kotlin.multiplatform.protocol.User -internal class JvmScopeProvider(private val scope: JvmScope) : Scope { - +internal class ScopeProvider(private val scope: JvmScope) : Scope { override var level: SentryLevel? set(value) { scope.level = value?.toJvmSentryLevel() diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.jvm.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.jvm.kt index 44479dfb..089c7efc 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.jvm.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.jvm.kt @@ -59,17 +59,17 @@ internal actual object SentryBridge { actual fun startTransaction(name: String, operation: String): Span { val jvmTransaction = Sentry.startTransaction(name, operation) - return JvmSpanProvider(jvmTransaction) + return SpanProvider(jvmTransaction) } actual fun startTransaction(name: String, operation: String, bindToScope: Boolean): Span { val jvmTransaction = Sentry.startTransaction(name, operation, bindToScope) - return JvmSpanProvider(jvmTransaction) + return SpanProvider(jvmTransaction) } actual fun getSpan(): Span? { val jvmSpan = Sentry.getSpan() - return jvmSpan?.let { JvmSpanProvider(it) } + return jvmSpan?.let { SpanProvider(it) } } actual fun close() { @@ -78,7 +78,7 @@ internal actual object SentryBridge { private fun configureScopeCallback(scopeCallback: ScopeCallback): (JvmScope) -> Unit { return { - val jvmScopeProvider = JvmScopeProvider(it) + val jvmScopeProvider = ScopeProvider(it) scopeCallback.invoke(jvmScopeProvider) } } diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/JvmSpanProvider.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SpanProvider.jvm.kt similarity index 92% rename from sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/JvmSpanProvider.kt rename to sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SpanProvider.jvm.kt index 1fe753df..d981bd99 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/JvmSpanProvider.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SpanProvider.jvm.kt @@ -5,15 +5,15 @@ import io.sentry.kotlin.multiplatform.extensions.toJvm import io.sentry.kotlin.multiplatform.extensions.toKmp import io.sentry.kotlin.multiplatform.protocol.SpanId -internal class JvmSpanProvider(private val jvmSpan: ISpan) : Span { +internal class SpanProvider(private val jvmSpan: ISpan) : Span { override fun startChild(operation: String): Span { val jvmSpan = jvmSpan.startChild(operation) - return JvmSpanProvider(jvmSpan) + return SpanProvider(jvmSpan) } override fun startChild(operation: String, description: String?): Span { val jvmSpan = jvmSpan.startChild(operation, description) - return JvmSpanProvider(jvmSpan) + return SpanProvider(jvmSpan) } override fun finish() { diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/JvmTransactionContextProvider.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContextProvider.jvm.kt similarity index 92% rename from sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/JvmTransactionContextProvider.kt rename to sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContextProvider.jvm.kt index 786b0461..05ec8764 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/JvmTransactionContextProvider.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContextProvider.jvm.kt @@ -5,7 +5,7 @@ import io.sentry.kotlin.multiplatform.protocol.SentryId import io.sentry.kotlin.multiplatform.protocol.SpanId import io.sentry.kotlin.multiplatform.protocol.TransactionNameSource -internal class JvmTransactionContextProvider(jvmTransactionContext: JvmTransactionContext) : +internal class TransactionContextProvider(jvmTransactionContext: JvmTransactionContext) : TransactionContext { override val name: String = jvmTransactionContext.name override val transactionNameSource: TransactionNameSource = diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.jvm.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.jvm.kt index d572a788..30f1a556 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.jvm.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.jvm.kt @@ -2,7 +2,7 @@ package io.sentry.kotlin.multiplatform.extensions import io.sentry.kotlin.multiplatform.BuildKonfig import io.sentry.kotlin.multiplatform.JvmSentryOptions -import io.sentry.kotlin.multiplatform.JvmTransactionContextProvider +import io.sentry.kotlin.multiplatform.TransactionContextProvider import io.sentry.kotlin.multiplatform.SamplingContext import io.sentry.kotlin.multiplatform.SentryEvent import io.sentry.kotlin.multiplatform.SentryOptions @@ -64,7 +64,7 @@ internal fun JvmSentryOptions.applyJvmBaseOptions(options: SentryOptions) { } } setTracesSampler { jvmSamplingContext -> - val jvmTransactionContext = JvmTransactionContextProvider(jvmSamplingContext.transactionContext) + val jvmTransactionContext = TransactionContextProvider(jvmSamplingContext.transactionContext) val transactionContext = TransactionContextAdapter(jvmTransactionContext) val samplingContext = SamplingContext(transactionContext) // returns null if KMP tracesSampler is null diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/TransactionNameSourceExtensions.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/TransactionNameSourceExtensions.jvm.kt similarity index 100% rename from sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/TransactionNameSourceExtensions.kt rename to sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/TransactionNameSourceExtensions.jvm.kt diff --git a/sentry-kotlin-multiplatform/src/commonJvmTest/kotlin/io/sentry/kotlin/multiplatform/BaseSentryScopeTest.kt b/sentry-kotlin-multiplatform/src/commonJvmTest/kotlin/io/sentry/kotlin/multiplatform/BaseSentryScopeTest.kt index 37431deb..c6ae0278 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmTest/kotlin/io/sentry/kotlin/multiplatform/BaseSentryScopeTest.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmTest/kotlin/io/sentry/kotlin/multiplatform/BaseSentryScopeTest.kt @@ -5,6 +5,6 @@ import io.sentry.SentryOptions actual abstract class BaseSentryScopeTest { actual fun initializeScope(): Scope { val jvmScope = JvmScope(SentryOptions()) - return JvmScopeProvider(jvmScope) + return ScopeProvider(jvmScope) } } diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContext.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContext.kt index 93001c4a..8ad2247a 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContext.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContext.kt @@ -2,11 +2,12 @@ package io.sentry.kotlin.multiplatform import io.sentry.kotlin.multiplatform.protocol.TransactionNameSource -public class TransactionContextAdapter constructor(private val transactionContext: TransactionContext) : - TransactionContext by transactionContext - +/** An interface representing the context of a transaction. */ public interface TransactionContext : SpanContext { public val name: String public val transactionNameSource: TransactionNameSource public val parentSampled: Boolean -} \ No newline at end of file +} + +internal class TransactionContextAdapter constructor(private val transactionContext: TransactionContext) : + TransactionContext by transactionContext \ No newline at end of file diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TracesSamplerRateTest.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TracesSamplerRateTest.kt index 2d89d253..c1a68b69 100644 --- a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TracesSamplerRateTest.kt +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TracesSamplerRateTest.kt @@ -3,12 +3,12 @@ package io.sentry.kotlin.multiplatform import io.sentry.kotlin.multiplatform.protocol.SentryId import io.sentry.kotlin.multiplatform.protocol.SpanId import io.sentry.kotlin.multiplatform.protocol.TransactionNameSource -import io.sentry.kotlin.multiplatform.utils.createMockTransactionContext +import io.sentry.kotlin.multiplatform.utils.createFakeTransactionContext import kotlin.test.BeforeTest import kotlin.test.Test import kotlin.test.assertEquals -class MockTransactionContext( +class FakeTransactionContext( override val operation: String, override val traceId: SentryId, override val spanId: SpanId, @@ -25,7 +25,7 @@ class TracesSamplerRateTest { @BeforeTest fun setup() { - mockTransactionContext = createMockTransactionContext() + mockTransactionContext = createFakeTransactionContext() } @Test @@ -74,7 +74,7 @@ class TracesSamplerRateTest { // Assert that the sample rate is 0.1 val differentSamplingContext = SamplingContext( - transactionContext = createMockTransactionContext(name = "different"), + transactionContext = createFakeTransactionContext(name = "different"), ) val differentSampleRate = options.tracesSampler?.invoke(differentSamplingContext) assertEquals(0.1, differentSampleRate) diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TransactionIntegrationTest.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TransactionIntegrationTest.kt index 71158f83..06ac3964 100644 --- a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TransactionIntegrationTest.kt +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TransactionIntegrationTest.kt @@ -5,7 +5,6 @@ import kotlin.test.Test import kotlin.test.assertEquals class TransactionIntegrationTest: BaseSentryTest() { - @Test fun `tracesSampler can receive correct TransactionContext name`() { val expectedName = "test" diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/utils/MockSamplingContextFactory.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/utils/MockSamplingContextFactory.kt index ac488a3b..cd25758b 100644 --- a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/utils/MockSamplingContextFactory.kt +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/utils/MockSamplingContextFactory.kt @@ -1,12 +1,12 @@ package io.sentry.kotlin.multiplatform.utils -import io.sentry.kotlin.multiplatform.MockTransactionContext +import io.sentry.kotlin.multiplatform.FakeTransactionContext import io.sentry.kotlin.multiplatform.TransactionContext import io.sentry.kotlin.multiplatform.protocol.SentryId import io.sentry.kotlin.multiplatform.protocol.SpanId import io.sentry.kotlin.multiplatform.protocol.TransactionNameSource -fun createMockTransactionContext( +fun createFakeTransactionContext( operation: String = "test", traceId: SentryId = SentryId.EMPTY_ID, spanId: SpanId = SpanId.EMPTY_ID, @@ -17,7 +17,7 @@ fun createMockTransactionContext( transactionNameSource: TransactionNameSource = TransactionNameSource.TASK, parentSampled: Boolean = false ): TransactionContext { - return MockTransactionContext( + return FakeTransactionContext( operation = operation, traceId = traceId, spanId = spanId, diff --git a/sentry-samples/kmp-app-cocoapods/androidApp/build.gradle.kts b/sentry-samples/kmp-app-cocoapods/androidApp/build.gradle.kts index 3e70dcaf..88cabc1a 100644 --- a/sentry-samples/kmp-app-cocoapods/androidApp/build.gradle.kts +++ b/sentry-samples/kmp-app-cocoapods/androidApp/build.gradle.kts @@ -32,7 +32,7 @@ android { } dependencies { - implementation(rootProject.project(":sentry-samples:kmp-app-spm:shared")) + implementation(rootProject.project(":sentry-samples:kmp-app-cocoapods:shared")) implementation("com.google.android.material:material:1.6.1") implementation("androidx.appcompat:appcompat:1.4.2") implementation("androidx.constraintlayout:constraintlayout:2.1.4") From 50688e28bbdb048384f3750540d7b7d1295509bc Mon Sep 17 00:00:00 2001 From: GIancarlo Buenaflor Date: Thu, 23 Nov 2023 11:55:31 +0100 Subject: [PATCH 15/43] Fix test --- .../io/sentry/kotlin/multiplatform/BaseSentryScopeTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sentry-kotlin-multiplatform/src/commonAppleTest/kotlin/io/sentry/kotlin/multiplatform/BaseSentryScopeTest.kt b/sentry-kotlin-multiplatform/src/commonAppleTest/kotlin/io/sentry/kotlin/multiplatform/BaseSentryScopeTest.kt index 9efd2cda..dc17644f 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleTest/kotlin/io/sentry/kotlin/multiplatform/BaseSentryScopeTest.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleTest/kotlin/io/sentry/kotlin/multiplatform/BaseSentryScopeTest.kt @@ -5,6 +5,6 @@ import cocoapods.Sentry.SentryScope as CocoaScope actual abstract class BaseSentryScopeTest { actual fun initializeScope(): Scope { val cocoaScope = CocoaScope() - return `ScopeProvider.apple`(cocoaScope) + return ScopeProvider(cocoaScope) } } From 201eb34a93ba008a418ff26b8c000e31acdff234 Mon Sep 17 00:00:00 2001 From: GIancarlo Buenaflor Date: Thu, 23 Nov 2023 12:01:36 +0100 Subject: [PATCH 16/43] Add comments --- .../kotlin/io/sentry/kotlin/multiplatform/Span.kt | 13 ++++++++++--- .../kotlin/multiplatform/TransactionContext.kt | 5 +++++ .../multiplatform/protocol/TransactionNameSource.kt | 1 + 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Span.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Span.kt index 25e07095..6b47357e 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Span.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Span.kt @@ -2,6 +2,7 @@ package io.sentry.kotlin.multiplatform import io.sentry.kotlin.multiplatform.protocol.SpanId +/** Represents a performance monitoring Span. */ public interface Span { /** * Starts a child Span. @@ -46,12 +47,18 @@ public interface Span { public val parentSpanId: SpanId? /** - * Sets the tag on span or transaction. + * Sets the tag on span. * * @param key the tag key * @param value the tag value */ public fun setTag(key: String, value: String) + + /** + * Returns the tag value from span. + * + * @return the tag value + */ public fun getTag(key: String): String? /** @@ -62,7 +69,7 @@ public interface Span { public val isFinished: Boolean /** - * Sets extra data on span or transaction. + * Sets extra data on span. * * @param key the data key * @param value the data value @@ -70,7 +77,7 @@ public interface Span { public fun setData(key: String, value: Any) /** - * Returns extra data from span or transaction. + * Returns extra data from span. * * @return the data */ diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContext.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContext.kt index 8ad2247a..a5cf71e8 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContext.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContext.kt @@ -4,8 +4,13 @@ import io.sentry.kotlin.multiplatform.protocol.TransactionNameSource /** An interface representing the context of a transaction. */ public interface TransactionContext : SpanContext { + /** The name of the transaction. */ public val name: String + + /** The source of the transaction name. */ public val transactionNameSource: TransactionNameSource + + /** Indicates if the parent transaction is sampled. */ public val parentSampled: Boolean } diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/protocol/TransactionNameSource.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/protocol/TransactionNameSource.kt index 1d99ebf8..d66d01e4 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/protocol/TransactionNameSource.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/protocol/TransactionNameSource.kt @@ -1,5 +1,6 @@ package io.sentry.kotlin.multiplatform.protocol +/** The source of the transaction name. */ public enum class TransactionNameSource { /** * User-defined name From 9d59d285f72f020a4e6f1609db241d0433bc134c Mon Sep 17 00:00:00 2001 From: GIancarlo Buenaflor Date: Thu, 23 Nov 2023 12:16:19 +0100 Subject: [PATCH 17/43] Formatting --- config/detekt/baseline.xml | 4 ++-- config/detekt/detekt.yml | 11 +++++++-- .../multiplatform/SpanProvider.apple.kt | 2 +- .../TransactionContextProvider.apple.kt | 2 +- .../SentryOptionsExtensions.apple.kt | 5 ++-- .../SentrySampleDecisionExtensions.kt | 2 +- .../TransactionNameSourceExtensions.apple.kt | 2 +- .../kotlin/multiplatform/protocol/SpanId.kt | 1 - .../kotlin/multiplatform/SpanProvider.jvm.kt | 2 +- .../TransactionContextProvider.jvm.kt | 2 +- .../kotlin/multiplatform/TypeAliases.jvm.kt | 9 ++++--- .../extensions/SentryOptionsExtensions.jvm.kt | 5 ++-- .../extensions/SpanStatusExtensions.kt | 2 +- .../TransactionNameSourceExtensions.jvm.kt | 2 +- .../sentry/kotlin/multiplatform/Attachment.kt | 3 --- .../kotlin/multiplatform/SamplingContext.kt | 7 +++++- .../sentry/kotlin/multiplatform/SentryDate.kt | 4 +++- .../sentry/kotlin/multiplatform/SentryKMP.kt | 8 +------ .../sentry/kotlin/multiplatform/SpanStatus.kt | 1 + .../multiplatform/TransactionContext.kt | 4 ++-- .../kotlin/multiplatform/protocol/SpanId.kt | 4 +++- .../multiplatform/TracesSamplerRateTest.kt | 24 +++++++++---------- .../TransactionIntegrationTest.kt | 4 ++-- .../sample/kmp/app/android/MainActivity.kt | 1 - .../kotlin/sample.kmp.app/SentrySetup.kt | 1 - 25 files changed, 58 insertions(+), 54 deletions(-) diff --git a/config/detekt/baseline.xml b/config/detekt/baseline.xml index fb608a17..77b17b8f 100644 --- a/config/detekt/baseline.xml +++ b/config/detekt/baseline.xml @@ -2,9 +2,9 @@ - SwallowedException:CocoaScopeProvider.kt$CocoaScopeProvider$e: Throwable + SwallowedException:ScopeProvider.apple.kt$ScopeProvider$e: Throwable SwallowedException:SentryLevel.kt$SentryLevel.Companion$throwable: Throwable - TooGenericExceptionCaught:CocoaScopeProvider.kt$CocoaScopeProvider$e: Throwable + TooGenericExceptionCaught:ScopeProvider.apple.kt$ScopeProvider$e: Throwable TooGenericExceptionCaught:SentryLevel.kt$SentryLevel.Companion$throwable: Throwable TooGenericExceptionThrown:SentryKMP.kt$Sentry$throw RuntimeException("Uncaught Exception from Kotlin Multiplatform.") diff --git a/config/detekt/detekt.yml b/config/detekt/detekt.yml index 818763de..53a4a87d 100644 --- a/config/detekt/detekt.yml +++ b/config/detekt/detekt.yml @@ -13,6 +13,10 @@ style: UnusedPrivateMember: excludes: - "**/Attachment.kt" + MagicNumber: + excludes: + - "**/SpanStatus.*" + - "**/TransactionNameSourceExtensions.*" naming: MatchingDeclarationName: active: false @@ -21,12 +25,15 @@ complexity: excludes: [ "**/SentryKMP.kt", "**/SentryBridge.*", - "**/CocoaScopeProvider.kt", + "**/ScopeProvider.*", "**/Scope.kt", - "**/JvmScopeProvider.kt", "**/Breadcrumb.kt", ] LongMethod: excludes: - "**/SentryOptionsExtensions.*" + CyclomaticComplexMethod: + excludes: + - "**/SpanStatusExtensions.*" + - "**/SentryOptionsExtensions.*" diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SpanProvider.apple.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SpanProvider.apple.kt index e98c8206..220e239f 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SpanProvider.apple.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SpanProvider.apple.kt @@ -67,4 +67,4 @@ internal class SpanProvider(private val cocoaSpan: SentrySpanProtocol) : Span { override fun getData(key: String): Any? { return cocoaSpan.data[key] } -} \ No newline at end of file +} diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContextProvider.apple.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContextProvider.apple.kt index 300f1856..ec5651bf 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContextProvider.apple.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContextProvider.apple.kt @@ -19,4 +19,4 @@ internal class TransactionContextProvider(cocoaTransactionContext: CocoaTransact override val parentSpanId: SpanId? = cocoaTransactionContext.parentSpanId?.let { SpanId(it.toString()) } override val description: String? = cocoaTransactionContext.spanDescription -} \ No newline at end of file +} diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.apple.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.apple.kt index efe91abd..775279d6 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.apple.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.apple.kt @@ -5,11 +5,11 @@ import cocoapods.Sentry.SentryHttpStatusCodeRange import io.sentry.kotlin.multiplatform.BuildKonfig import io.sentry.kotlin.multiplatform.CocoaSentryEvent import io.sentry.kotlin.multiplatform.CocoaSentryOptions -import io.sentry.kotlin.multiplatform.TransactionContextProvider import io.sentry.kotlin.multiplatform.SamplingContext import io.sentry.kotlin.multiplatform.SentryEvent import io.sentry.kotlin.multiplatform.SentryOptions import io.sentry.kotlin.multiplatform.TransactionContextAdapter +import io.sentry.kotlin.multiplatform.TransactionContextProvider import io.sentry.kotlin.multiplatform.nsexception.dropKotlinCrashEvent import kotlinx.cinterop.convert import platform.Foundation.NSNumber @@ -104,7 +104,8 @@ internal fun CocoaSentryOptions.applyCocoaBaseOptions(options: SentryOptions) { failedRequestTargets = options.failedRequestTargets failedRequestStatusCodes = options.failedRequestStatusCodes.map { SentryHttpStatusCodeRange( - min = it.min.convert(), max = it.max.convert() + min = it.min.convert(), + max = it.max.convert() ) } } diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentrySampleDecisionExtensions.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentrySampleDecisionExtensions.kt index 099ba308..d1fd91a7 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentrySampleDecisionExtensions.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentrySampleDecisionExtensions.kt @@ -14,4 +14,4 @@ internal fun SentrySampleDecision.toBoolean(): Boolean = when (this) { internal fun Boolean.toSampleDecision(): SentrySampleDecision = when (this) { false -> SentrySampleDecision.kSentrySampleDecisionNo true -> SentrySampleDecision.kSentrySampleDecisionYes -} \ No newline at end of file +} diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/TransactionNameSourceExtensions.apple.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/TransactionNameSourceExtensions.apple.kt index 9c24b3cf..f476d3b9 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/TransactionNameSourceExtensions.apple.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/TransactionNameSourceExtensions.apple.kt @@ -28,4 +28,4 @@ internal fun NSInteger.toKmpTransactionNameSource(): TransactionNameSource { else -> TransactionNameSource.CUSTOM } return transactionNameSource -} \ No newline at end of file +} diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/protocol/SpanId.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/protocol/SpanId.kt index 57329103..5603159a 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/protocol/SpanId.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/protocol/SpanId.kt @@ -1,6 +1,5 @@ package io.sentry.kotlin.multiplatform.protocol -import io.sentry.kotlin.multiplatform.CocoaSentryId import io.sentry.kotlin.multiplatform.CocoaSpanId public actual data class SpanId actual constructor(val spanIdString: String) { diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SpanProvider.jvm.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SpanProvider.jvm.kt index d981bd99..310f48f6 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SpanProvider.jvm.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SpanProvider.jvm.kt @@ -63,4 +63,4 @@ internal class SpanProvider(private val jvmSpan: ISpan) : Span { override fun getData(key: String): Any? { return jvmSpan.getData(key) } -} \ No newline at end of file +} diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContextProvider.jvm.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContextProvider.jvm.kt index 05ec8764..d83975e1 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContextProvider.jvm.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContextProvider.jvm.kt @@ -18,4 +18,4 @@ internal class TransactionContextProvider(jvmTransactionContext: JvmTransactionC override val parentSpanId: SpanId? = jvmTransactionContext.parentSpanId?.let { SpanId(it.toString()) } override val description: String? = jvmTransactionContext.description -} \ No newline at end of file +} diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/TypeAliases.jvm.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/TypeAliases.jvm.kt index eaa04408..e29ea786 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/TypeAliases.jvm.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/TypeAliases.jvm.kt @@ -2,21 +2,20 @@ package io.sentry.kotlin.multiplatform import io.sentry.Attachment import io.sentry.Breadcrumb -import io.sentry.Instrumenter import io.sentry.Scope import io.sentry.SentryEvent import io.sentry.SentryLevel import io.sentry.SentryOptions import io.sentry.SpanId +import io.sentry.SpanStatus +import io.sentry.TransactionContext import io.sentry.UserFeedback import io.sentry.protocol.Contexts import io.sentry.protocol.Message import io.sentry.protocol.SentryException import io.sentry.protocol.SentryId -import io.sentry.protocol.User -import io.sentry.SpanStatus -import io.sentry.TransactionContext import io.sentry.protocol.TransactionNameSource +import io.sentry.protocol.User internal typealias JvmSentryLevel = SentryLevel internal typealias JvmUser = User @@ -33,4 +32,4 @@ internal typealias JvmContexts = Contexts internal typealias JvmSpanStatus = SpanStatus internal typealias JvmSpanId = SpanId internal typealias JvmTransactionContext = TransactionContext -internal typealias JvmTransactionNameSource = TransactionNameSource \ No newline at end of file +internal typealias JvmTransactionNameSource = TransactionNameSource diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.jvm.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.jvm.kt index 30f1a556..d36da0eb 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.jvm.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.jvm.kt @@ -2,11 +2,11 @@ package io.sentry.kotlin.multiplatform.extensions import io.sentry.kotlin.multiplatform.BuildKonfig import io.sentry.kotlin.multiplatform.JvmSentryOptions -import io.sentry.kotlin.multiplatform.TransactionContextProvider import io.sentry.kotlin.multiplatform.SamplingContext import io.sentry.kotlin.multiplatform.SentryEvent import io.sentry.kotlin.multiplatform.SentryOptions import io.sentry.kotlin.multiplatform.TransactionContextAdapter +import io.sentry.kotlin.multiplatform.TransactionContextProvider internal fun SentryOptions.toJvmSentryOptionsCallback(): (JvmSentryOptions) -> Unit = { it.applyJvmBaseOptions(this) @@ -27,7 +27,6 @@ internal fun SentryOptions.toJvmSentryOptionsCallback(): (JvmSentryOptions) -> U } } - /** * Applies the given base SentryOptions to this JvmSentryOption * This avoids code duplication during init on Android @@ -71,4 +70,4 @@ internal fun JvmSentryOptions.applyJvmBaseOptions(options: SentryOptions) { val sampleRate = options.tracesSampler?.invoke(samplingContext) sampleRate } -} \ No newline at end of file +} diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SpanStatusExtensions.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SpanStatusExtensions.kt index 48b9f257..b40e0f75 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SpanStatusExtensions.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SpanStatusExtensions.kt @@ -47,4 +47,4 @@ internal fun JvmSpanStatus.toKmp(): SpanStatus { SpanStatus.UNKNOWN } } -} \ No newline at end of file +} diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/TransactionNameSourceExtensions.jvm.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/TransactionNameSourceExtensions.jvm.kt index 15cf73a4..4c15dfc6 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/TransactionNameSourceExtensions.jvm.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/TransactionNameSourceExtensions.jvm.kt @@ -10,4 +10,4 @@ internal fun JvmTransactionNameSource.toKmp(): TransactionNameSource = when (thi JvmTransactionNameSource.VIEW -> TransactionNameSource.VIEW JvmTransactionNameSource.TASK -> TransactionNameSource.TASK JvmTransactionNameSource.CUSTOM -> TransactionNameSource.CUSTOM -} \ No newline at end of file +} diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Attachment.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Attachment.kt index 72dac24a..e38013bd 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Attachment.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Attachment.kt @@ -32,6 +32,3 @@ public expect class Attachment { public constructor(pathname: String, filename: String, contentType: String?) } - - -public class MyHint : Exception() \ No newline at end of file diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SamplingContext.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SamplingContext.kt index 8d465bbd..1d6d8ea8 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SamplingContext.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SamplingContext.kt @@ -1,5 +1,10 @@ package io.sentry.kotlin.multiplatform +/** + * Context used by [io.sentry.kotlin.multiplatform.SentryOptions.tracesSampler] to determine if transaction + * is going to be sampled. + */ public data class SamplingContext( - public val transactionContext: TransactionContext, + /** The transaction context. */ + public val transactionContext: TransactionContext ) diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryDate.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryDate.kt index 3434a9ae..3d06a567 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryDate.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryDate.kt @@ -1,5 +1,6 @@ package io.sentry.kotlin.multiplatform +/** An interface representing a date. */ public abstract class SentryDate : Comparable { /** Returns the date in nanoseconds as long. */ public abstract fun nanoTimestamp(): Long @@ -8,7 +9,8 @@ public abstract class SentryDate : Comparable { * Calculates a date by using another date. * * - * This is a workaround for limited precision offered in some cases (e.g. when using [ ]). This makes it possible to have high precision duration by using + * This is a workaround for limited precision offered in some cases (e.g. when using [ ]). + * This makes it possible to have high precision duration by using * nanoseconds for the finish timestamp where normally the start and finish timestamps would only * offer millisecond precision. * diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryKMP.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryKMP.kt index acc67e63..96a30fda 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryKMP.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryKMP.kt @@ -4,12 +4,6 @@ import io.sentry.kotlin.multiplatform.protocol.Breadcrumb import io.sentry.kotlin.multiplatform.protocol.SentryId import io.sentry.kotlin.multiplatform.protocol.User import io.sentry.kotlin.multiplatform.protocol.UserFeedback -import kotlinx.coroutines.CancellationException -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.currentCoroutineContext -import kotlinx.coroutines.withContext -import kotlin.coroutines.AbstractCoroutineContextElement -import kotlin.coroutines.CoroutineContext import kotlin.experimental.ExperimentalObjCRefinement import kotlin.native.HiddenFromObjC @@ -170,4 +164,4 @@ public object Sentry { public fun close() { SentryBridge.close() } -} \ No newline at end of file +} diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SpanStatus.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SpanStatus.kt index 1658fa09..dbd548f1 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SpanStatus.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SpanStatus.kt @@ -1,5 +1,6 @@ package io.sentry.kotlin.multiplatform +/** The status of a [Span]. */ public enum class SpanStatus { /** Not an error, returned on success. */ OK(200, 299), diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContext.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContext.kt index a5cf71e8..81e423e9 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContext.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContext.kt @@ -2,7 +2,7 @@ package io.sentry.kotlin.multiplatform import io.sentry.kotlin.multiplatform.protocol.TransactionNameSource -/** An interface representing the context of a transaction. */ +/** The Transaction Context defines the metadata for a Performance Monitoring Transaction. */ public interface TransactionContext : SpanContext { /** The name of the transaction. */ public val name: String @@ -15,4 +15,4 @@ public interface TransactionContext : SpanContext { } internal class TransactionContextAdapter constructor(private val transactionContext: TransactionContext) : - TransactionContext by transactionContext \ No newline at end of file + TransactionContext by transactionContext diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/protocol/SpanId.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/protocol/SpanId.kt index e4676756..cd295d4c 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/protocol/SpanId.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/protocol/SpanId.kt @@ -1,8 +1,10 @@ package io.sentry.kotlin.multiplatform.protocol +/** The unique ID of a [io.sentry.kotlin.multiplatform.Span]. */ public expect class SpanId(spanIdString: String) { public companion object { + /** Returns a new empty SpanId */ public val EMPTY_ID: SpanId } override fun toString(): String -} \ No newline at end of file +} diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TracesSamplerRateTest.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TracesSamplerRateTest.kt index c1a68b69..8ec5b816 100644 --- a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TracesSamplerRateTest.kt +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TracesSamplerRateTest.kt @@ -35,7 +35,7 @@ class TracesSamplerRateTest { null } val samplingContext = SamplingContext( - transactionContext = mockTransactionContext, + transactionContext = mockTransactionContext ) val sampleRate = options.tracesSampler?.invoke(samplingContext) assertEquals(null, sampleRate) @@ -48,7 +48,7 @@ class TracesSamplerRateTest { 0.5 } val samplingContext = SamplingContext( - transactionContext = mockTransactionContext, + transactionContext = mockTransactionContext ) val sampleRate = options.tracesSampler?.invoke(samplingContext) assertEquals(0.5, sampleRate) @@ -67,14 +67,14 @@ class TracesSamplerRateTest { // Assert that the sample rate is 0.5 val samplingContext = SamplingContext( - transactionContext = mockTransactionContext, + transactionContext = mockTransactionContext ) val sampleRate = options.tracesSampler?.invoke(samplingContext) assertEquals(0.5, sampleRate) // Assert that the sample rate is 0.1 val differentSamplingContext = SamplingContext( - transactionContext = createFakeTransactionContext(name = "different"), + transactionContext = createFakeTransactionContext(name = "different") ) val differentSampleRate = options.tracesSampler?.invoke(differentSamplingContext) assertEquals(0.1, differentSampleRate) @@ -91,7 +91,7 @@ class TracesSamplerRateTest { } val samplingContext = SamplingContext( - transactionContext = mockTransactionContext, + transactionContext = mockTransactionContext ) options.tracesSampler?.invoke(samplingContext) assertEquals(expectedName, actualName) @@ -108,7 +108,7 @@ class TracesSamplerRateTest { } val samplingContext = SamplingContext( - transactionContext = mockTransactionContext, + transactionContext = mockTransactionContext ) options.tracesSampler?.invoke(samplingContext) assertEquals(expectedSpanId, actualSpanId) @@ -125,7 +125,7 @@ class TracesSamplerRateTest { } val samplingContext = SamplingContext( - transactionContext = mockTransactionContext, + transactionContext = mockTransactionContext ) options.tracesSampler?.invoke(samplingContext) assertEquals(expectedParentSpanId, actualParentSpanId) @@ -142,7 +142,7 @@ class TracesSamplerRateTest { } val samplingContext = SamplingContext( - transactionContext = mockTransactionContext, + transactionContext = mockTransactionContext ) options.tracesSampler?.invoke(samplingContext) assertEquals(expectedDescription, actualDescription) @@ -159,7 +159,7 @@ class TracesSamplerRateTest { } val samplingContext = SamplingContext( - transactionContext = mockTransactionContext, + transactionContext = mockTransactionContext ) options.tracesSampler?.invoke(samplingContext) assertEquals(expectedSampled, actualSampled) @@ -176,7 +176,7 @@ class TracesSamplerRateTest { } val samplingContext = SamplingContext( - transactionContext = mockTransactionContext, + transactionContext = mockTransactionContext ) options.tracesSampler?.invoke(samplingContext) assertEquals(expectedParentSampled, actualParentSampled) @@ -193,7 +193,7 @@ class TracesSamplerRateTest { } val samplingContext = SamplingContext( - transactionContext = mockTransactionContext, + transactionContext = mockTransactionContext ) options.tracesSampler?.invoke(samplingContext) assertEquals(expectedOperation, actualOperation) @@ -210,7 +210,7 @@ class TracesSamplerRateTest { } val samplingContext = SamplingContext( - transactionContext = mockTransactionContext, + transactionContext = mockTransactionContext ) options.tracesSampler?.invoke(samplingContext) assertEquals(expectedTransactionNameSource, actualTransactionNameSource) diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TransactionIntegrationTest.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TransactionIntegrationTest.kt index 06ac3964..37c66f7e 100644 --- a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TransactionIntegrationTest.kt +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TransactionIntegrationTest.kt @@ -4,7 +4,7 @@ import io.sentry.kotlin.multiplatform.utils.fakeDsn import kotlin.test.Test import kotlin.test.assertEquals -class TransactionIntegrationTest: BaseSentryTest() { +class TransactionIntegrationTest : BaseSentryTest() { @Test fun `tracesSampler can receive correct TransactionContext name`() { val expectedName = "test" @@ -134,4 +134,4 @@ class TransactionIntegrationTest: BaseSentryTest() { transaction.finish() assertEquals(expectedSampled, actualSampled) } -} \ No newline at end of file +} diff --git a/sentry-samples/kmp-app-spm/androidApp/src/main/java/sample/kmp/app/android/MainActivity.kt b/sentry-samples/kmp-app-spm/androidApp/src/main/java/sample/kmp/app/android/MainActivity.kt index b957dc0a..388efb17 100644 --- a/sentry-samples/kmp-app-spm/androidApp/src/main/java/sample/kmp/app/android/MainActivity.kt +++ b/sentry-samples/kmp-app-spm/androidApp/src/main/java/sample/kmp/app/android/MainActivity.kt @@ -13,7 +13,6 @@ import sample.kmp.app.configureSentryScope import sample.kmp.app.initializeSentry import java.io.FileOutputStream import java.io.IOException -import java.lang.Thread.sleep class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { diff --git a/sentry-samples/kmp-app-spm/shared/src/commonMain/kotlin/sample.kmp.app/SentrySetup.kt b/sentry-samples/kmp-app-spm/shared/src/commonMain/kotlin/sample.kmp.app/SentrySetup.kt index 6d4a4839..7516e93a 100644 --- a/sentry-samples/kmp-app-spm/shared/src/commonMain/kotlin/sample.kmp.app/SentrySetup.kt +++ b/sentry-samples/kmp-app-spm/shared/src/commonMain/kotlin/sample.kmp.app/SentrySetup.kt @@ -4,7 +4,6 @@ import io.sentry.kotlin.multiplatform.Attachment import io.sentry.kotlin.multiplatform.HttpStatusCodeRange import io.sentry.kotlin.multiplatform.OptionsConfiguration import io.sentry.kotlin.multiplatform.Sentry -import io.sentry.kotlin.multiplatform.SpanStatus /** Configure scope applicable to all platforms */ fun configureSentryScope() { From d9d2cc8d6ce37f3da65e88290dd89a757b7a604f Mon Sep 17 00:00:00 2001 From: GIancarlo Buenaflor Date: Thu, 23 Nov 2023 14:12:02 +0100 Subject: [PATCH 18/43] Adjust tests --- .../sentry/kotlin/multiplatform/SentryDate.kt | 41 --- .../kotlin/multiplatform/SpanStatusTest.kt | 81 ++++++ .../sentry/kotlin/multiplatform/SpanTest.kt | 134 +++++++++ .../multiplatform/TracesSamplerRateTest.kt | 260 ++++++++++-------- .../TransactionIntegrationTest.kt | 137 --------- .../FakeTransactionContext.kt} | 14 +- 6 files changed, 379 insertions(+), 288 deletions(-) delete mode 100644 sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryDate.kt create mode 100644 sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SpanStatusTest.kt create mode 100644 sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SpanTest.kt delete mode 100644 sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TransactionIntegrationTest.kt rename sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/{utils/MockSamplingContextFactory.kt => fakes/FakeTransactionContext.kt} (70%) diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryDate.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryDate.kt deleted file mode 100644 index 3d06a567..00000000 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryDate.kt +++ /dev/null @@ -1,41 +0,0 @@ -package io.sentry.kotlin.multiplatform - -/** An interface representing a date. */ -public abstract class SentryDate : Comparable { - /** Returns the date in nanoseconds as long. */ - public abstract fun nanoTimestamp(): Long - - /** - * Calculates a date by using another date. - * - * - * This is a workaround for limited precision offered in some cases (e.g. when using [ ]). - * This makes it possible to have high precision duration by using - * nanoseconds for the finish timestamp where normally the start and finish timestamps would only - * offer millisecond precision. - * - * @param otherDate another [SentryDate] - * @return date in seconds as long - */ - public fun laterDateNanosTimestampByDiff(otherDate: SentryDate?): Long { - return if (otherDate != null && compareTo(otherDate) < 0) { - otherDate.nanoTimestamp() - } else { - nanoTimestamp() - } - } - - /** - * Difference between two dates in nanoseconds. - * - * @param otherDate another [SentryDate] - * @return difference in nanoseconds - */ - public fun diff(otherDate: SentryDate): Long { - return nanoTimestamp() - otherDate.nanoTimestamp() - } - - public override fun compareTo(other: SentryDate?): Int { - return nanoTimestamp().compareTo(other?.nanoTimestamp() ?: 0) - } -} diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SpanStatusTest.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SpanStatusTest.kt new file mode 100644 index 00000000..1f2b6b3d --- /dev/null +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SpanStatusTest.kt @@ -0,0 +1,81 @@ +package io.sentry.kotlin.multiplatform + +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertNull + +class SpanStatusTest { + @Test + fun `GIVEN http status code in a matching range WHEN converting to SpanStatus THEN returns corresponding SpanStatus`() { + // GIVEN + val httpStatusCode = 202 + + // WHEN + val convertedStatus = SpanStatus.fromHttpStatusCode(httpStatusCode) + + // THEN + assertEquals(SpanStatus.OK, convertedStatus) + } + + @Test + fun `GIVEN specific http status code WHEN converting to SpanStatus THEN returns corresponding SpanStatus`() { + // GIVEN + val httpStatusCode = 504 + + // WHEN + val convertedStatus = SpanStatus.fromHttpStatusCode(httpStatusCode) + + // THEN + assertEquals(SpanStatus.DEADLINE_EXCEEDED, convertedStatus) + } + + @Test + fun `GIVEN http status code matching multiple statuses WHEN converting to SpanStatus THEN returns the first matching SpanStatus`() { + // GIVEN + val httpStatusCode = 500 + + // WHEN + val convertedStatus = SpanStatus.fromHttpStatusCode(httpStatusCode) + + // THEN + assertEquals(SpanStatus.INTERNAL_ERROR, convertedStatus) + } + + @Test + fun `GIVEN http status code with no matching SpanStatus WHEN converting to SpanStatus THEN returns null`() { + // GIVEN + val httpStatusCode = 302 + + // WHEN + val convertedStatus = SpanStatus.fromHttpStatusCode(httpStatusCode) + + // THEN + assertNull(convertedStatus) + } + + @Test + fun `GIVEN http status code with no matching SpanStatus AND default value provided WHEN converting to SpanStatus THEN returns the default value`() { + // GIVEN + val httpStatusCode = 302 + val defaultValue = SpanStatus.UNKNOWN_ERROR + + // WHEN + val convertedStatus = SpanStatus.fromHttpStatusCode(httpStatusCode, defaultValue) + + // THEN + assertEquals(defaultValue, convertedStatus) + } + + @Test + fun `GIVEN null http status code AND default value provided WHEN converting to SpanStatus THEN returns the default value`() { + // GIVEN + val httpStatusCode: Int? = null + val defaultValue = SpanStatus.UNKNOWN_ERROR + + // WHEN + val convertedStatus = SpanStatus.fromHttpStatusCode(httpStatusCode, defaultValue) + + // THEN + assertEquals(defaultValue, convertedStatus) + } +} diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SpanTest.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SpanTest.kt new file mode 100644 index 00000000..0af2230f --- /dev/null +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SpanTest.kt @@ -0,0 +1,134 @@ +package io.sentry.kotlin.multiplatform + +import io.sentry.kotlin.multiplatform.utils.fakeDsn +import kotlin.test.BeforeTest +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertNull + +class SpanTest { + class Fixture { + private val operation = "test" + private val description = "test description" + + internal fun getSut(bindToScope: Boolean = false): Span { + return Sentry.startTransaction(operation, description, bindToScope) + } + } + + private lateinit var fixture: Fixture + + @BeforeTest + fun setup() { + fixture = Fixture() + } + + @Test + fun `GIVEN Sentry init AND tracesSampler set WHEN transaction finishes THEN receive correct name`() { + // GIVEN + val expectedName = "test" + var actualName = "" + Sentry.init { + it.dsn = fakeDsn + it.tracesSampler = { context -> + actualName = context.transactionContext.name + null + } + } + + // WHEN + val transaction = fixture.getSut() + transaction.finish() + + // THEN + assertEquals(expectedName, actualName) + } + + @Test + fun `GIVEN Sentry init AND tracesSampler set WHEN transaction started and finishes THEN receive correct spanId`() { + // GIVEN + var actualSpanId = "" + Sentry.init { + it.dsn = fakeDsn + it.tracesSampler = { context -> + actualSpanId = context.transactionContext.spanId.toString() + null + } + } + + // WHEN + val transaction = fixture.getSut() + transaction.finish() + + // THEN + assertEquals(transaction.spanId.toString(), actualSpanId) + } + + @Test + fun `GIVEN Sentry init AND parent + child spans WHEN both started and finished THEN child parentSpanId equals spanId of parent`() { + // GIVEN + Sentry.init { + it.dsn = fakeDsn + } + + // WHEN + val transaction = fixture.getSut() + val child = transaction.startChild("child") + child.finish() + transaction.finish() + + // THEN + assertEquals(child.parentSpanId?.toString(), transaction.spanId.toString()) + } + + @Test + fun `GIVEN Sentry init WHEN transaction with bindToScope enabled started AND getSpan called THEN should return the correct transaction`() { + // GIVEN + Sentry.init { + it.dsn = fakeDsn + } + + // WHEN + val transaction = fixture.getSut(bindToScope = true) + val activeTransactionSpanId = Sentry.getSpan()?.spanId + + // THEN + assertEquals( + activeTransactionSpanId, + transaction.spanId, + "activeTransactionSpanId should be equal to transaction.spanId" + ) + transaction.finish() + } + + @Test + fun `GIVEN Sentry init WHEN transaction with bindToScope disabled started AND getSpan called THEN getSpan should be null`() { + // GIVEN + Sentry.init { + it.dsn = fakeDsn + } + + // WHEN + val transaction = fixture.getSut() + val activeTransactionSpanId = Sentry.getSpan()?.spanId + + // THEN + assertNull(activeTransactionSpanId) + transaction.finish() + } + + @Test + fun `GIVEN Sentry init WHEN transaction with bindToScope enabled starts and finishes THEN calling getSpan after should be null`() { + // GIVEN + Sentry.init { + it.dsn = fakeDsn + } + + // WHEN + val transaction = fixture.getSut(bindToScope = true) + transaction.finish() + + // THEN + assertNull(Sentry.getSpan()?.spanId) + } +} diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TracesSamplerRateTest.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TracesSamplerRateTest.kt index 8ec5b816..948d85e5 100644 --- a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TracesSamplerRateTest.kt +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TracesSamplerRateTest.kt @@ -1,9 +1,11 @@ package io.sentry.kotlin.multiplatform +import io.sentry.kotlin.multiplatform.fakes.FakeTransactionContext +import io.sentry.kotlin.multiplatform.fakes.createFakeTransactionContext import io.sentry.kotlin.multiplatform.protocol.SentryId import io.sentry.kotlin.multiplatform.protocol.SpanId import io.sentry.kotlin.multiplatform.protocol.TransactionNameSource -import io.sentry.kotlin.multiplatform.utils.createFakeTransactionContext +import io.sentry.kotlin.multiplatform.utils.fakeDsn import kotlin.test.BeforeTest import kotlin.test.Test import kotlin.test.assertEquals @@ -21,198 +23,238 @@ class FakeTransactionContext( ) : TransactionContext class TracesSamplerRateTest { - private lateinit var mockTransactionContext: TransactionContext + class Fixture { + var sampler: ((SamplingContext) -> Double?)? = null + + private fun getSamplingContext(transactionContext: TransactionContext): SamplingContext { + return SamplingContext(transactionContext) + } + + internal fun getSut( + transactionContext: TransactionContext = createFakeTransactionContext(), + sampler: (SamplingContext) -> Double?, + ): SamplingContext { + this.sampler = sampler + return getSamplingContext(transactionContext) + } + } + + private fun SamplingContext.getSampleRate(): Double? { + return fixture.sampler?.invoke(this) + } + + private lateinit var fixture: Fixture @BeforeTest fun setup() { - mockTransactionContext = createFakeTransactionContext() + fixture = Fixture() } @Test - fun `tracesSampler can return null sample rate`() { - val options = SentryOptions() - options.tracesSampler = { - null - } - val samplingContext = SamplingContext( - transactionContext = mockTransactionContext - ) - val sampleRate = options.tracesSampler?.invoke(samplingContext) - assertEquals(null, sampleRate) + fun `GIVEN null sampleRate WHEN tracesSampler callback set to sampleRate THEN return null sample rate`() { + // GIVEN + val sampleRate = null + + // WHEN + val sut = fixture.getSut { sampleRate } + + // THEM + assertEquals(sampleRate, sut.getSampleRate()) } @Test - fun `tracesSampler can return sample rate`() { - val options = SentryOptions() - options.tracesSampler = { - 0.5 - } - val samplingContext = SamplingContext( - transactionContext = mockTransactionContext - ) - val sampleRate = options.tracesSampler?.invoke(samplingContext) - assertEquals(0.5, sampleRate) + fun `GIVEN sampleRate WHEN traceSampler callback set to sampleRate THEN return correct sample rate`() { + // GIVEN + val sampleRate = 0.5 + + // WHEN + val sut = fixture.getSut { sampleRate } + + // THEN + assertEquals(sampleRate, sut.getSampleRate()) } @Test - fun `tracesSampler can return different sample rate`() { - val options = SentryOptions() - options.tracesSampler = { - if (it.transactionContext.name == "test") { - 0.5 + fun `GIVEN different sampleRates WHEN traceSampler callback set to sampleRates THEN can return different sample rates`() { + // GIVEN + val sampleRate1 = 0.5 + val sampleRate2 = 0.1 + + // WHEN + val sut = fixture.getSut { + if (it.transactionContext.name == "random") { + sampleRate1 } else { - 0.1 + sampleRate2 } } - // Assert that the sample rate is 0.5 - val samplingContext = SamplingContext( - transactionContext = mockTransactionContext - ) - val sampleRate = options.tracesSampler?.invoke(samplingContext) - assertEquals(0.5, sampleRate) - - // Assert that the sample rate is 0.1 - val differentSamplingContext = SamplingContext( - transactionContext = createFakeTransactionContext(name = "different") - ) - val differentSampleRate = options.tracesSampler?.invoke(differentSamplingContext) - assertEquals(0.1, differentSampleRate) + // THEN + assertEquals(sampleRate2, sut.getSampleRate()) } @Test - fun `tracerSampler returns correct TransactionContext name`() { - val options = SentryOptions() - val expectedName = "test" + fun `GIVEN transactionContext name WHEN tracerSampler set AND sampled THEN returns correct TransactionContext name`() { + // GIVEN + val expectedName = "testName" + val transactionContext = createFakeTransactionContext(name = expectedName) + + // WHEN var actualName = "" - options.tracesSampler = { + val sut = fixture.getSut(transactionContext = transactionContext) { actualName = it.transactionContext.name null } + sut.getSampleRate() - val samplingContext = SamplingContext( - transactionContext = mockTransactionContext - ) - options.tracesSampler?.invoke(samplingContext) + // THEN assertEquals(expectedName, actualName) } @Test - fun `tracerSampler returns correct TransactionContext spanId`() { - val options = SentryOptions() - val expectedSpanId = mockTransactionContext.spanId + fun `GIVEN transactionContext spanId WHEN tracerSampler set AND sampled THEN returns correct TransactionContext spanId`() { + // GIVEN + val expectedSpanId = SpanId("123") + val transactionContext = createFakeTransactionContext(spanId = expectedSpanId) + + // WHEN var actualSpanId: SpanId? = null - options.tracesSampler = { + val sut = fixture.getSut(transactionContext = transactionContext) { actualSpanId = it.transactionContext.spanId null } + sut.getSampleRate() - val samplingContext = SamplingContext( - transactionContext = mockTransactionContext - ) - options.tracesSampler?.invoke(samplingContext) + // THEN assertEquals(expectedSpanId, actualSpanId) } @Test - fun `tracerSampler returns correct TransactionContext parentSpanId`() { - val options = SentryOptions() - val expectedParentSpanId = mockTransactionContext.parentSpanId + fun `GIVEN transactionContext parentSpanId WHEN tracerSampler set AND sampled THEN returns correct TransactionContext parentSpanId`() { + // GIVEN + val expectedParentSpanId = SpanId("123") + val transactionContext = createFakeTransactionContext(parentSpanId = expectedParentSpanId) + + // WHEN var actualParentSpanId: SpanId? = null - options.tracesSampler = { + val sut = fixture.getSut(transactionContext = transactionContext) { actualParentSpanId = it.transactionContext.parentSpanId null } + sut.getSampleRate() - val samplingContext = SamplingContext( - transactionContext = mockTransactionContext - ) - options.tracesSampler?.invoke(samplingContext) + // THEN assertEquals(expectedParentSpanId, actualParentSpanId) } @Test - fun `tracerSampler returns correct TransactionContext description`() { - val options = SentryOptions() - val expectedDescription = mockTransactionContext.description + fun `GIVEN transactionContext description WHEN tracerSampler set AND sampled THEN returns correct TransactionContext description`() { + // GIVEN + val expectedDescription = "testDescription" + val transactionContext = createFakeTransactionContext(description = expectedDescription) + + // WHEN var actualDescription: String? = null - options.tracesSampler = { + val sut = fixture.getSut(transactionContext = transactionContext) { actualDescription = it.transactionContext.description null } + sut.getSampleRate() - val samplingContext = SamplingContext( - transactionContext = mockTransactionContext - ) - options.tracesSampler?.invoke(samplingContext) + // THEN assertEquals(expectedDescription, actualDescription) } @Test - fun `tracerSampler returns correct TransactionContext sampled`() { - val options = SentryOptions() - val expectedSampled = mockTransactionContext.sampled + fun `GIVEN transactionContext sampled WHEN tracerSampler set AND sampled THEN returns correct TransactionContext sampled`() { + // GIVEN + val expectedSampled = false + val transactionContext = createFakeTransactionContext(sampled = expectedSampled) + + // WHEN var actualSampled: Boolean? = null - options.tracesSampler = { + val sut = fixture.getSut(transactionContext = transactionContext) { actualSampled = it.transactionContext.sampled null } + sut.getSampleRate() - val samplingContext = SamplingContext( - transactionContext = mockTransactionContext - ) - options.tracesSampler?.invoke(samplingContext) + // THEN assertEquals(expectedSampled, actualSampled) } @Test - fun `tracerSampler returns correct TransactionContext parentSampled`() { - val options = SentryOptions() - val expectedParentSampled = mockTransactionContext.parentSampled + fun `GIVEN transactionContext parentSampled WHEN tracerSampler set AND sampled THEN returns correct TransactionContext parentSampled`() { + // GIVEN + val expectedParentSampled = false + val transactionContext = createFakeTransactionContext(parentSampled = expectedParentSampled) + + // WHEN var actualParentSampled: Boolean? = null - options.tracesSampler = { + val sut = fixture.getSut(transactionContext = transactionContext) { actualParentSampled = it.transactionContext.parentSampled null } + sut.getSampleRate() - val samplingContext = SamplingContext( - transactionContext = mockTransactionContext - ) - options.tracesSampler?.invoke(samplingContext) + // THEN assertEquals(expectedParentSampled, actualParentSampled) } @Test - fun `tracerSampler returns correct TransactionContext operation`() { - val options = SentryOptions() - val expectedOperation = mockTransactionContext.operation + fun `GIVEN transactionContext operation WHEN tracerSampler set AND sampled THEN returns correct TransactionContext operation`() { + // GIVEN + val expectedOperation = "testOperation" + val transactionContext = createFakeTransactionContext(operation = expectedOperation) + + // WHEN var actualOperation: String? = null - options.tracesSampler = { + val sut = fixture.getSut(transactionContext = transactionContext) { actualOperation = it.transactionContext.operation null } + sut.getSampleRate() - val samplingContext = SamplingContext( - transactionContext = mockTransactionContext - ) - options.tracesSampler?.invoke(samplingContext) + // THEN assertEquals(expectedOperation, actualOperation) } @Test - fun `tracerSampler returns correct TransactionContext transactionNameSource`() { - val options = SentryOptions() - val expectedTransactionNameSource = mockTransactionContext.transactionNameSource - var actualTransactionNameSource: TransactionNameSource? = null - options.tracesSampler = { - actualTransactionNameSource = it.transactionContext.transactionNameSource + fun `GIVEN transactionContext traceId WHEN tracerSampler set AND sampled THEN returns correct TransactionContext traceId`() { + // GIVEN + val expectedTraceId = SentryId("123") + val transactionContext = createFakeTransactionContext(traceId = expectedTraceId) + + // WHEN + var actualTraceId: SentryId? = null + val sut = fixture.getSut(transactionContext = transactionContext) { + actualTraceId = it.transactionContext.traceId null } + sut.getSampleRate() - val samplingContext = SamplingContext( - transactionContext = mockTransactionContext - ) - options.tracesSampler?.invoke(samplingContext) - assertEquals(expectedTransactionNameSource, actualTransactionNameSource) + // THEN + assertEquals(expectedTraceId, actualTraceId) + } + + @Test + fun `GIVEN tracesSampler set WHEN transaction finishes THEN tracesSampler receives correct TransactionContext operation`() { + // GIVEN + val expectedOperation = "testOperation" + var actualOperation = "" + Sentry.init { + it.dsn = fakeDsn + it.tracesSampler = { context -> + actualOperation = context.transactionContext.operation + null + } + } + val transaction = Sentry.startTransaction("test", "testOperation") + + // WHEN + transaction.finish() + + // THEN + assertEquals(expectedOperation, actualOperation) } } diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TransactionIntegrationTest.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TransactionIntegrationTest.kt deleted file mode 100644 index 37c66f7e..00000000 --- a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TransactionIntegrationTest.kt +++ /dev/null @@ -1,137 +0,0 @@ -package io.sentry.kotlin.multiplatform - -import io.sentry.kotlin.multiplatform.utils.fakeDsn -import kotlin.test.Test -import kotlin.test.assertEquals - -class TransactionIntegrationTest : BaseSentryTest() { - @Test - fun `tracesSampler can receive correct TransactionContext name`() { - val expectedName = "test" - var actualName = "" - sentryInit { - it.dsn = fakeDsn - it.tracesSampler = { context -> - actualName = context.transactionContext.name - null - } - } - val transaction = Sentry.startTransaction("test", "testOperation") - transaction.finish() - assertEquals(expectedName, actualName) - } - - @Test - fun `tracesSampler can receive correct TransactionContext spanId`() { - var actualSpanId = "" - sentryInit { - it.dsn = fakeDsn - it.tracesSampler = { context -> - actualSpanId = context.transactionContext.spanId.toString() - null - } - } - val transaction = Sentry.startTransaction("test", "testOperation") - transaction.finish() - assertEquals(transaction.spanId.toString(), actualSpanId) - } - - @Test - fun `parentSpanId is correct after starting child span`() { - sentryInit { - it.dsn = fakeDsn - } - val transaction = Sentry.startTransaction("test", "testOperation") - val child = transaction.startChild("child") - child.finish() - transaction.finish() - assertEquals(child.parentSpanId?.toString(), transaction.spanId.toString()) - } - - @Test - fun `getSpan returns the current active span with bindToScope enabled`() { - sentryInit { - it.dsn = fakeDsn - } - val transaction = Sentry.startTransaction("test", "testOperation", bindToScope = true) - val activeTransactionSpanId = Sentry.getSpan()?.spanId - transaction.finish() - assertEquals(activeTransactionSpanId, transaction.spanId, "activeTransactionSpanId should be equal to transaction.spanId") - } - - @Test - fun `getSpan returns null when bindToScope is disabled`() { - sentryInit { - it.dsn = fakeDsn - } - val transaction = Sentry.startTransaction("test", "testOperation", bindToScope = false) - val activeTransactionSpanId = Sentry.getSpan()?.spanId - val child = transaction.startChild("child") - val activeChildSpanId = Sentry.getSpan()?.spanId - child.finish() - transaction.finish() - assertEquals(activeTransactionSpanId, null) - assertEquals(activeChildSpanId, null) - } - - @Test - fun `getSpan returns null when Transaction has finished`() { - sentryInit { - it.dsn = fakeDsn - } - val transaction = Sentry.startTransaction("test", "testOperation", bindToScope = true) - val activeTransactionSpanId = Sentry.getSpan()?.spanId - transaction.finish() - val activeTransactionSpanIdAfterFinish = Sentry.getSpan()?.spanId - assertEquals(activeTransactionSpanId, transaction.spanId) - assertEquals(activeTransactionSpanIdAfterFinish, null) - } - - @Test - fun `tracesSampler can receive correct TransactionContext operation`() { - val expectedOperation = "testOperation" - var actualOperation = "" - sentryInit { - it.dsn = fakeDsn - it.tracesSampler = { context -> - actualOperation = context.transactionContext.operation - null - } - } - val transaction = Sentry.startTransaction("test", "testOperation") - transaction.finish() - assertEquals(expectedOperation, actualOperation) - } - - @Test - fun `tracesSampler can receive correct TransactionContext sampled`() { - val expectedSampled = false - var actualSampled: Boolean? = null - sentryInit { - it.dsn = fakeDsn - it.tracesSampler = { context -> - actualSampled = context.transactionContext.sampled - null - } - } - val transaction = Sentry.startTransaction("test", "testOperation") - transaction.finish() - assertEquals(expectedSampled, actualSampled) - } - - @Test - fun `tracesSampler can receive correct TransactionContext parentSampled`() { - val expectedSampled = false - var actualSampled: Boolean? = null - sentryInit { - it.dsn = fakeDsn - it.tracesSampler = { context -> - actualSampled = context.transactionContext.parentSampled - null - } - } - val transaction = Sentry.startTransaction("test", "testOperation") - transaction.finish() - assertEquals(expectedSampled, actualSampled) - } -} diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/utils/MockSamplingContextFactory.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/fakes/FakeTransactionContext.kt similarity index 70% rename from sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/utils/MockSamplingContextFactory.kt rename to sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/fakes/FakeTransactionContext.kt index cd25758b..fe6def78 100644 --- a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/utils/MockSamplingContextFactory.kt +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/fakes/FakeTransactionContext.kt @@ -1,4 +1,4 @@ -package io.sentry.kotlin.multiplatform.utils +package io.sentry.kotlin.multiplatform.fakes import io.sentry.kotlin.multiplatform.FakeTransactionContext import io.sentry.kotlin.multiplatform.TransactionContext @@ -6,6 +6,18 @@ import io.sentry.kotlin.multiplatform.protocol.SentryId import io.sentry.kotlin.multiplatform.protocol.SpanId import io.sentry.kotlin.multiplatform.protocol.TransactionNameSource +class FakeTransactionContext( + override val operation: String, + override val traceId: SentryId, + override val spanId: SpanId, + override val parentSpanId: SpanId?, + override val description: String?, + override val sampled: Boolean, + override val name: String, + override val transactionNameSource: TransactionNameSource, + override val parentSampled: Boolean +) : TransactionContext + fun createFakeTransactionContext( operation: String = "test", traceId: SentryId = SentryId.EMPTY_ID, From 71b7218d3bfc9113bb11b8fc0e8dcb7f3675e464 Mon Sep 17 00:00:00 2001 From: GIancarlo Buenaflor Date: Thu, 23 Nov 2023 14:16:02 +0100 Subject: [PATCH 19/43] improve --- .../multiplatform/TracesSamplerRateTest.kt | 36 ------------------- .../fakes/FakeTransactionContext.kt | 1 - 2 files changed, 37 deletions(-) diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TracesSamplerRateTest.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TracesSamplerRateTest.kt index 948d85e5..9b7ff168 100644 --- a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TracesSamplerRateTest.kt +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TracesSamplerRateTest.kt @@ -1,27 +1,12 @@ package io.sentry.kotlin.multiplatform -import io.sentry.kotlin.multiplatform.fakes.FakeTransactionContext import io.sentry.kotlin.multiplatform.fakes.createFakeTransactionContext import io.sentry.kotlin.multiplatform.protocol.SentryId import io.sentry.kotlin.multiplatform.protocol.SpanId -import io.sentry.kotlin.multiplatform.protocol.TransactionNameSource -import io.sentry.kotlin.multiplatform.utils.fakeDsn import kotlin.test.BeforeTest import kotlin.test.Test import kotlin.test.assertEquals -class FakeTransactionContext( - override val operation: String, - override val traceId: SentryId, - override val spanId: SpanId, - override val parentSpanId: SpanId?, - override val description: String?, - override val sampled: Boolean, - override val name: String, - override val transactionNameSource: TransactionNameSource, - override val parentSampled: Boolean -) : TransactionContext - class TracesSamplerRateTest { class Fixture { var sampler: ((SamplingContext) -> Double?)? = null @@ -236,25 +221,4 @@ class TracesSamplerRateTest { // THEN assertEquals(expectedTraceId, actualTraceId) } - - @Test - fun `GIVEN tracesSampler set WHEN transaction finishes THEN tracesSampler receives correct TransactionContext operation`() { - // GIVEN - val expectedOperation = "testOperation" - var actualOperation = "" - Sentry.init { - it.dsn = fakeDsn - it.tracesSampler = { context -> - actualOperation = context.transactionContext.operation - null - } - } - val transaction = Sentry.startTransaction("test", "testOperation") - - // WHEN - transaction.finish() - - // THEN - assertEquals(expectedOperation, actualOperation) - } } diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/fakes/FakeTransactionContext.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/fakes/FakeTransactionContext.kt index fe6def78..bdbb1707 100644 --- a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/fakes/FakeTransactionContext.kt +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/fakes/FakeTransactionContext.kt @@ -1,6 +1,5 @@ package io.sentry.kotlin.multiplatform.fakes -import io.sentry.kotlin.multiplatform.FakeTransactionContext import io.sentry.kotlin.multiplatform.TransactionContext import io.sentry.kotlin.multiplatform.protocol.SentryId import io.sentry.kotlin.multiplatform.protocol.SpanId From 39acf70b7de874f35ea2b234764214d590976a57 Mon Sep 17 00:00:00 2001 From: GIancarlo Buenaflor Date: Thu, 23 Nov 2023 14:24:24 +0100 Subject: [PATCH 20/43] improve --- .../kotlin/multiplatform/TracesSamplerRateTest.kt | 11 ++++++----- .../io/sentry/kotlin/multiplatform/utils/Constants.kt | 1 + 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TracesSamplerRateTest.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TracesSamplerRateTest.kt index 9b7ff168..fc020e1d 100644 --- a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TracesSamplerRateTest.kt +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TracesSamplerRateTest.kt @@ -3,13 +3,14 @@ package io.sentry.kotlin.multiplatform import io.sentry.kotlin.multiplatform.fakes.createFakeTransactionContext import io.sentry.kotlin.multiplatform.protocol.SentryId import io.sentry.kotlin.multiplatform.protocol.SpanId +import io.sentry.kotlin.multiplatform.utils.fakeSentryIdString import kotlin.test.BeforeTest import kotlin.test.Test import kotlin.test.assertEquals class TracesSamplerRateTest { class Fixture { - var sampler: ((SamplingContext) -> Double?)? = null + val options = SentryOptions() private fun getSamplingContext(transactionContext: TransactionContext): SamplingContext { return SamplingContext(transactionContext) @@ -19,13 +20,13 @@ class TracesSamplerRateTest { transactionContext: TransactionContext = createFakeTransactionContext(), sampler: (SamplingContext) -> Double?, ): SamplingContext { - this.sampler = sampler + this.options.tracesSampler = sampler return getSamplingContext(transactionContext) } } private fun SamplingContext.getSampleRate(): Double? { - return fixture.sampler?.invoke(this) + return fixture.options.tracesSampler?.invoke(this) } private lateinit var fixture: Fixture @@ -99,7 +100,7 @@ class TracesSamplerRateTest { @Test fun `GIVEN transactionContext spanId WHEN tracerSampler set AND sampled THEN returns correct TransactionContext spanId`() { // GIVEN - val expectedSpanId = SpanId("123") + val expectedSpanId = SpanId(fakeSentryIdString) val transactionContext = createFakeTransactionContext(spanId = expectedSpanId) // WHEN @@ -207,7 +208,7 @@ class TracesSamplerRateTest { @Test fun `GIVEN transactionContext traceId WHEN tracerSampler set AND sampled THEN returns correct TransactionContext traceId`() { // GIVEN - val expectedTraceId = SentryId("123") + val expectedTraceId = SentryId(fakeSentryIdString) val transactionContext = createFakeTransactionContext(traceId = expectedTraceId) // WHEN diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/utils/Constants.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/utils/Constants.kt index bbb38aa5..670eb5c5 100644 --- a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/utils/Constants.kt +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/utils/Constants.kt @@ -5,3 +5,4 @@ const val projectSlug = "sentry-kotlin-multiplatform" const val fakeDsn = "https://abc@def.ingest.sentry.io/1234567" const val realDsn = "https://83f281ded2844eda83a8a413b080dbb9@o447951.ingest.sentry.io/5903800" +const val fakeSentryIdString = "626261be1dac4fac90e469032d828390" From e29cb9c3a7a764ba9e2c6ff1ac979bd9f5e74f77 Mon Sep 17 00:00:00 2001 From: GIancarlo Buenaflor Date: Thu, 23 Nov 2023 14:24:46 +0100 Subject: [PATCH 21/43] Format --- .../io/sentry/kotlin/multiplatform/TracesSamplerRateTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TracesSamplerRateTest.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TracesSamplerRateTest.kt index fc020e1d..74863eed 100644 --- a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TracesSamplerRateTest.kt +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TracesSamplerRateTest.kt @@ -18,7 +18,7 @@ class TracesSamplerRateTest { internal fun getSut( transactionContext: TransactionContext = createFakeTransactionContext(), - sampler: (SamplingContext) -> Double?, + sampler: (SamplingContext) -> Double? ): SamplingContext { this.options.tracesSampler = sampler return getSamplingContext(transactionContext) From 9d652335e512c15e228e2202e8d1c80143157f44 Mon Sep 17 00:00:00 2001 From: GIancarlo Buenaflor Date: Thu, 23 Nov 2023 14:30:11 +0100 Subject: [PATCH 22/43] Update demos --- .../shared/src/commonMain/kotlin/sample.kmp.app/LoginImpl.kt | 3 +++ .../kotlin/sentry.kmp.demo/models/AuthenticationViewModel.kt | 3 +++ .../shared/src/commonMain/kotlin/sample.kmp.app/LoginImpl.kt | 3 +++ 3 files changed, 9 insertions(+) diff --git a/sentry-samples/kmp-app-cocoapods/shared/src/commonMain/kotlin/sample.kmp.app/LoginImpl.kt b/sentry-samples/kmp-app-cocoapods/shared/src/commonMain/kotlin/sample.kmp.app/LoginImpl.kt index 19a837d3..41e99190 100644 --- a/sentry-samples/kmp-app-cocoapods/shared/src/commonMain/kotlin/sample.kmp.app/LoginImpl.kt +++ b/sentry-samples/kmp-app-cocoapods/shared/src/commonMain/kotlin/sample.kmp.app/LoginImpl.kt @@ -19,6 +19,8 @@ object LoginImpl { try { validateUsername(username) } catch (exception: InvalidUsernameException) { + val activeSpan = Sentry.getSpan() + activeSpan?.startChild("child demo span", "child demo span description") val sentryId = Sentry.captureException(exception) { val breadcrumb = Breadcrumb.debug("this is a test breadcrumb") breadcrumb.setData("touch event", "on login") @@ -38,6 +40,7 @@ object LoginImpl { comments = "I had an error during login on ${Platform().platform}" } Sentry.captureUserFeedback(userFeedback) + activeSpan?.finish() } catch (exception: IllegalArgumentException) { throw exception } finally { diff --git a/sentry-samples/kmp-app-mvvm-di/shared/src/commonMain/kotlin/sentry.kmp.demo/models/AuthenticationViewModel.kt b/sentry-samples/kmp-app-mvvm-di/shared/src/commonMain/kotlin/sentry.kmp.demo/models/AuthenticationViewModel.kt index 2c7d9326..d6c76df7 100644 --- a/sentry-samples/kmp-app-mvvm-di/shared/src/commonMain/kotlin/sentry.kmp.demo/models/AuthenticationViewModel.kt +++ b/sentry-samples/kmp-app-mvvm-di/shared/src/commonMain/kotlin/sentry.kmp.demo/models/AuthenticationViewModel.kt @@ -14,6 +14,8 @@ class AuthenticationViewModel : ViewModel() { try { throw LoginException("Error logging in") } catch (exception: Exception) { + val activeSpan = Sentry.getSpan() + activeSpan?.startChild("child demo span", "child demo span description") Sentry.captureException(exception) { val breadcrumb = Breadcrumb.error("Error during login").apply { setData("touch event", "on login") @@ -23,6 +25,7 @@ class AuthenticationViewModel : ViewModel() { it.setTag("login", "failed") it.level = SentryLevel.ERROR } + activeSpan?.finish() false } finally { transaction.finish() diff --git a/sentry-samples/kmp-app-spm/shared/src/commonMain/kotlin/sample.kmp.app/LoginImpl.kt b/sentry-samples/kmp-app-spm/shared/src/commonMain/kotlin/sample.kmp.app/LoginImpl.kt index 19a837d3..41e99190 100644 --- a/sentry-samples/kmp-app-spm/shared/src/commonMain/kotlin/sample.kmp.app/LoginImpl.kt +++ b/sentry-samples/kmp-app-spm/shared/src/commonMain/kotlin/sample.kmp.app/LoginImpl.kt @@ -19,6 +19,8 @@ object LoginImpl { try { validateUsername(username) } catch (exception: InvalidUsernameException) { + val activeSpan = Sentry.getSpan() + activeSpan?.startChild("child demo span", "child demo span description") val sentryId = Sentry.captureException(exception) { val breadcrumb = Breadcrumb.debug("this is a test breadcrumb") breadcrumb.setData("touch event", "on login") @@ -38,6 +40,7 @@ object LoginImpl { comments = "I had an error during login on ${Platform().platform}" } Sentry.captureUserFeedback(userFeedback) + activeSpan?.finish() } catch (exception: IllegalArgumentException) { throw exception } finally { From 7fc7469db73c8c78bb4e04d82fc9d944a2b08591 Mon Sep 17 00:00:00 2001 From: GIancarlo Buenaflor Date: Thu, 23 Nov 2023 14:44:52 +0100 Subject: [PATCH 23/43] Update CHANGELOG --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 604a22a0..9cd4234a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## Unreleased + +### Features + +- Add APM ([#155](https://github.com/getsentry/sentry-kotlin-multiplatform/pull/155)) + ## 0.3.0 ### Features From aaafa5e9cbeca1757c255d75773829427f52ab77 Mon Sep 17 00:00:00 2001 From: GIancarlo Buenaflor Date: Thu, 23 Nov 2023 14:45:28 +0100 Subject: [PATCH 24/43] Update API --- .../android/sentry-kotlin-multiplatform.api | 114 ++++++++++++++++++ .../api/jvm/sentry-kotlin-multiplatform.api | 114 ++++++++++++++++++ 2 files changed, 228 insertions(+) diff --git a/sentry-kotlin-multiplatform/api/android/sentry-kotlin-multiplatform.api b/sentry-kotlin-multiplatform/api/android/sentry-kotlin-multiplatform.api index 074d7115..81393cf9 100644 --- a/sentry-kotlin-multiplatform/api/android/sentry-kotlin-multiplatform.api +++ b/sentry-kotlin-multiplatform/api/android/sentry-kotlin-multiplatform.api @@ -45,6 +45,24 @@ public final class io/sentry/kotlin/multiplatform/HttpStatusCodeRange { public final class io/sentry/kotlin/multiplatform/HttpStatusCodeRange$Companion { } +public final class io/sentry/kotlin/multiplatform/Instrumenter : java/lang/Enum { + public static final field OTEL Lio/sentry/kotlin/multiplatform/Instrumenter; + public static final field SENTRY Lio/sentry/kotlin/multiplatform/Instrumenter; + public static fun valueOf (Ljava/lang/String;)Lio/sentry/kotlin/multiplatform/Instrumenter; + public static fun values ()[Lio/sentry/kotlin/multiplatform/Instrumenter; +} + +public final class io/sentry/kotlin/multiplatform/SamplingContext { + public fun (Lio/sentry/kotlin/multiplatform/TransactionContext;)V + public final fun component1 ()Lio/sentry/kotlin/multiplatform/TransactionContext; + public final fun copy (Lio/sentry/kotlin/multiplatform/TransactionContext;)Lio/sentry/kotlin/multiplatform/SamplingContext; + public static synthetic fun copy$default (Lio/sentry/kotlin/multiplatform/SamplingContext;Lio/sentry/kotlin/multiplatform/TransactionContext;ILjava/lang/Object;)Lio/sentry/kotlin/multiplatform/SamplingContext; + public fun equals (Ljava/lang/Object;)Z + public final fun getTransactionContext ()Lio/sentry/kotlin/multiplatform/TransactionContext; + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + public abstract interface class io/sentry/kotlin/multiplatform/Scope { public abstract fun addAttachment (Lio/sentry/kotlin/multiplatform/Attachment;)V public abstract fun addBreadcrumb (Lio/sentry/kotlin/multiplatform/protocol/Breadcrumb;)V @@ -82,9 +100,12 @@ public final class io/sentry/kotlin/multiplatform/Sentry { public final fun close ()V public final fun configureScope (Lkotlin/jvm/functions/Function1;)V public final fun crash ()V + public final fun getSpan ()Lio/sentry/kotlin/multiplatform/Span; public final fun init (Landroid/content/Context;Lkotlin/jvm/functions/Function1;)V public final fun init (Lkotlin/jvm/functions/Function1;)V public final fun setUser (Lio/sentry/kotlin/multiplatform/protocol/User;)V + public final fun startTransaction (Ljava/lang/String;Ljava/lang/String;)Lio/sentry/kotlin/multiplatform/Span; + public final fun startTransaction (Ljava/lang/String;Ljava/lang/String;Z)Lio/sentry/kotlin/multiplatform/Span; } public abstract class io/sentry/kotlin/multiplatform/SentryBaseEvent { @@ -177,6 +198,7 @@ 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 getTracesSampler ()Lkotlin/jvm/functions/Function1; public final fun setAttachScreenshot (Z)V public final fun setAttachStackTrace (Z)V public final fun setAttachThreads (Z)V @@ -198,6 +220,71 @@ public class io/sentry/kotlin/multiplatform/SentryOptions { public final fun setSdk (Lio/sentry/kotlin/multiplatform/protocol/SdkVersion;)V public final fun setSessionTrackingIntervalMillis (J)V public final fun setTracesSampleRate (Ljava/lang/Double;)V + public final fun setTracesSampler (Lkotlin/jvm/functions/Function1;)V +} + +public abstract interface class io/sentry/kotlin/multiplatform/Span { + public abstract fun finish ()V + public abstract fun finish (Lio/sentry/kotlin/multiplatform/SpanStatus;)V + public abstract fun getData (Ljava/lang/String;)Ljava/lang/Object; + public abstract fun getDescription ()Ljava/lang/String; + public abstract fun getOperation ()Ljava/lang/String; + public abstract fun getParentSpanId ()Lio/sentry/kotlin/multiplatform/protocol/SpanId; + public abstract fun getSpanId ()Lio/sentry/kotlin/multiplatform/protocol/SpanId; + public abstract fun getStatus ()Lio/sentry/kotlin/multiplatform/SpanStatus; + public abstract fun getTag (Ljava/lang/String;)Ljava/lang/String; + public abstract fun isFinished ()Z + public abstract fun setData (Ljava/lang/String;Ljava/lang/Object;)V + public abstract fun setDescription (Ljava/lang/String;)V + public abstract fun setOperation (Ljava/lang/String;)V + public abstract fun setStatus (Lio/sentry/kotlin/multiplatform/SpanStatus;)V + public abstract fun setTag (Ljava/lang/String;Ljava/lang/String;)V + public abstract fun startChild (Ljava/lang/String;)Lio/sentry/kotlin/multiplatform/Span; + public abstract fun startChild (Ljava/lang/String;Ljava/lang/String;)Lio/sentry/kotlin/multiplatform/Span; +} + +public abstract interface class io/sentry/kotlin/multiplatform/SpanContext { + public abstract fun getDescription ()Ljava/lang/String; + public abstract fun getOperation ()Ljava/lang/String; + public abstract fun getParentSpanId ()Lio/sentry/kotlin/multiplatform/protocol/SpanId; + public abstract fun getSampled ()Z + public abstract fun getSpanId ()Lio/sentry/kotlin/multiplatform/protocol/SpanId; + public abstract fun getTraceId ()Lio/sentry/kotlin/multiplatform/protocol/SentryId; +} + +public final class io/sentry/kotlin/multiplatform/SpanStatus : java/lang/Enum { + public static final field ABORTED Lio/sentry/kotlin/multiplatform/SpanStatus; + public static final field ALREADY_EXISTS Lio/sentry/kotlin/multiplatform/SpanStatus; + public static final field CANCELLED Lio/sentry/kotlin/multiplatform/SpanStatus; + public static final field Companion Lio/sentry/kotlin/multiplatform/SpanStatus$Companion; + public static final field DATA_LOSS Lio/sentry/kotlin/multiplatform/SpanStatus; + public static final field DEADLINE_EXCEEDED Lio/sentry/kotlin/multiplatform/SpanStatus; + public static final field FAILED_PRECONDITION Lio/sentry/kotlin/multiplatform/SpanStatus; + public static final field INTERNAL_ERROR Lio/sentry/kotlin/multiplatform/SpanStatus; + public static final field INVALID_ARGUMENT Lio/sentry/kotlin/multiplatform/SpanStatus; + public static final field NOT_FOUND Lio/sentry/kotlin/multiplatform/SpanStatus; + public static final field OK Lio/sentry/kotlin/multiplatform/SpanStatus; + public static final field OUT_OF_RANGE Lio/sentry/kotlin/multiplatform/SpanStatus; + public static final field PERMISSION_DENIED Lio/sentry/kotlin/multiplatform/SpanStatus; + public static final field RESOURCE_EXHAUSTED Lio/sentry/kotlin/multiplatform/SpanStatus; + public static final field UNAUTHENTICATED Lio/sentry/kotlin/multiplatform/SpanStatus; + public static final field UNAVAILABLE Lio/sentry/kotlin/multiplatform/SpanStatus; + public static final field UNIMPLEMENTED Lio/sentry/kotlin/multiplatform/SpanStatus; + public static final field UNKNOWN Lio/sentry/kotlin/multiplatform/SpanStatus; + public static final field UNKNOWN_ERROR Lio/sentry/kotlin/multiplatform/SpanStatus; + public static fun valueOf (Ljava/lang/String;)Lio/sentry/kotlin/multiplatform/SpanStatus; + public static fun values ()[Lio/sentry/kotlin/multiplatform/SpanStatus; +} + +public final class io/sentry/kotlin/multiplatform/SpanStatus$Companion { + public final fun fromHttpStatusCode (I)Lio/sentry/kotlin/multiplatform/SpanStatus; + public final fun fromHttpStatusCode (Ljava/lang/Integer;Lio/sentry/kotlin/multiplatform/SpanStatus;)Lio/sentry/kotlin/multiplatform/SpanStatus; +} + +public abstract interface class io/sentry/kotlin/multiplatform/TransactionContext : io/sentry/kotlin/multiplatform/SpanContext { + public abstract fun getName ()Ljava/lang/String; + public abstract fun getParentSampled ()Z + public abstract fun getTransactionNameSource ()Lio/sentry/kotlin/multiplatform/protocol/TransactionNameSource; } public final class io/sentry/kotlin/multiplatform/protocol/Breadcrumb { @@ -326,6 +413,33 @@ public final class io/sentry/kotlin/multiplatform/protocol/SentryId$Companion { public final fun getEMPTY_ID ()Lio/sentry/kotlin/multiplatform/protocol/SentryId; } +public final class io/sentry/kotlin/multiplatform/protocol/SpanId { + public static final field Companion Lio/sentry/kotlin/multiplatform/protocol/SpanId$Companion; + public fun (Ljava/lang/String;)V + public final fun component1 ()Ljava/lang/String; + public final fun copy (Ljava/lang/String;)Lio/sentry/kotlin/multiplatform/protocol/SpanId; + public static synthetic fun copy$default (Lio/sentry/kotlin/multiplatform/protocol/SpanId;Ljava/lang/String;ILjava/lang/Object;)Lio/sentry/kotlin/multiplatform/protocol/SpanId; + public fun equals (Ljava/lang/Object;)Z + public final fun getSpanIdString ()Ljava/lang/String; + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public final class io/sentry/kotlin/multiplatform/protocol/SpanId$Companion { + public final fun getEMPTY_ID ()Lio/sentry/kotlin/multiplatform/protocol/SpanId; +} + +public final class io/sentry/kotlin/multiplatform/protocol/TransactionNameSource : java/lang/Enum { + public static final field COMPONENT Lio/sentry/kotlin/multiplatform/protocol/TransactionNameSource; + public static final field CUSTOM Lio/sentry/kotlin/multiplatform/protocol/TransactionNameSource; + public static final field ROUTE Lio/sentry/kotlin/multiplatform/protocol/TransactionNameSource; + public static final field TASK Lio/sentry/kotlin/multiplatform/protocol/TransactionNameSource; + public static final field URL Lio/sentry/kotlin/multiplatform/protocol/TransactionNameSource; + public static final field VIEW Lio/sentry/kotlin/multiplatform/protocol/TransactionNameSource; + public static fun valueOf (Ljava/lang/String;)Lio/sentry/kotlin/multiplatform/protocol/TransactionNameSource; + public static fun values ()[Lio/sentry/kotlin/multiplatform/protocol/TransactionNameSource; +} + public final class io/sentry/kotlin/multiplatform/protocol/User { public fun ()V public fun (Lio/sentry/kotlin/multiplatform/protocol/User;)V diff --git a/sentry-kotlin-multiplatform/api/jvm/sentry-kotlin-multiplatform.api b/sentry-kotlin-multiplatform/api/jvm/sentry-kotlin-multiplatform.api index c79819de..6940da51 100644 --- a/sentry-kotlin-multiplatform/api/jvm/sentry-kotlin-multiplatform.api +++ b/sentry-kotlin-multiplatform/api/jvm/sentry-kotlin-multiplatform.api @@ -42,6 +42,24 @@ public final class io/sentry/kotlin/multiplatform/HttpStatusCodeRange { public final class io/sentry/kotlin/multiplatform/HttpStatusCodeRange$Companion { } +public final class io/sentry/kotlin/multiplatform/Instrumenter : java/lang/Enum { + public static final field OTEL Lio/sentry/kotlin/multiplatform/Instrumenter; + public static final field SENTRY Lio/sentry/kotlin/multiplatform/Instrumenter; + public static fun valueOf (Ljava/lang/String;)Lio/sentry/kotlin/multiplatform/Instrumenter; + public static fun values ()[Lio/sentry/kotlin/multiplatform/Instrumenter; +} + +public final class io/sentry/kotlin/multiplatform/SamplingContext { + public fun (Lio/sentry/kotlin/multiplatform/TransactionContext;)V + public final fun component1 ()Lio/sentry/kotlin/multiplatform/TransactionContext; + public final fun copy (Lio/sentry/kotlin/multiplatform/TransactionContext;)Lio/sentry/kotlin/multiplatform/SamplingContext; + public static synthetic fun copy$default (Lio/sentry/kotlin/multiplatform/SamplingContext;Lio/sentry/kotlin/multiplatform/TransactionContext;ILjava/lang/Object;)Lio/sentry/kotlin/multiplatform/SamplingContext; + public fun equals (Ljava/lang/Object;)Z + public final fun getTransactionContext ()Lio/sentry/kotlin/multiplatform/TransactionContext; + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + public abstract interface class io/sentry/kotlin/multiplatform/Scope { public abstract fun addAttachment (Lio/sentry/kotlin/multiplatform/Attachment;)V public abstract fun addBreadcrumb (Lio/sentry/kotlin/multiplatform/protocol/Breadcrumb;)V @@ -79,9 +97,12 @@ public final class io/sentry/kotlin/multiplatform/Sentry { public final fun close ()V public final fun configureScope (Lkotlin/jvm/functions/Function1;)V public final fun crash ()V + public final fun getSpan ()Lio/sentry/kotlin/multiplatform/Span; public final fun init (Lio/sentry/kotlin/multiplatform/Context;Lkotlin/jvm/functions/Function1;)V public final fun init (Lkotlin/jvm/functions/Function1;)V public final fun setUser (Lio/sentry/kotlin/multiplatform/protocol/User;)V + public final fun startTransaction (Ljava/lang/String;Ljava/lang/String;)Lio/sentry/kotlin/multiplatform/Span; + public final fun startTransaction (Ljava/lang/String;Ljava/lang/String;Z)Lio/sentry/kotlin/multiplatform/Span; } public abstract class io/sentry/kotlin/multiplatform/SentryBaseEvent { @@ -174,6 +195,7 @@ 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 getTracesSampler ()Lkotlin/jvm/functions/Function1; public final fun setAttachScreenshot (Z)V public final fun setAttachStackTrace (Z)V public final fun setAttachThreads (Z)V @@ -195,6 +217,71 @@ public class io/sentry/kotlin/multiplatform/SentryOptions { public final fun setSdk (Lio/sentry/kotlin/multiplatform/protocol/SdkVersion;)V public final fun setSessionTrackingIntervalMillis (J)V public final fun setTracesSampleRate (Ljava/lang/Double;)V + public final fun setTracesSampler (Lkotlin/jvm/functions/Function1;)V +} + +public abstract interface class io/sentry/kotlin/multiplatform/Span { + public abstract fun finish ()V + public abstract fun finish (Lio/sentry/kotlin/multiplatform/SpanStatus;)V + public abstract fun getData (Ljava/lang/String;)Ljava/lang/Object; + public abstract fun getDescription ()Ljava/lang/String; + public abstract fun getOperation ()Ljava/lang/String; + public abstract fun getParentSpanId ()Lio/sentry/kotlin/multiplatform/protocol/SpanId; + public abstract fun getSpanId ()Lio/sentry/kotlin/multiplatform/protocol/SpanId; + public abstract fun getStatus ()Lio/sentry/kotlin/multiplatform/SpanStatus; + public abstract fun getTag (Ljava/lang/String;)Ljava/lang/String; + public abstract fun isFinished ()Z + public abstract fun setData (Ljava/lang/String;Ljava/lang/Object;)V + public abstract fun setDescription (Ljava/lang/String;)V + public abstract fun setOperation (Ljava/lang/String;)V + public abstract fun setStatus (Lio/sentry/kotlin/multiplatform/SpanStatus;)V + public abstract fun setTag (Ljava/lang/String;Ljava/lang/String;)V + public abstract fun startChild (Ljava/lang/String;)Lio/sentry/kotlin/multiplatform/Span; + public abstract fun startChild (Ljava/lang/String;Ljava/lang/String;)Lio/sentry/kotlin/multiplatform/Span; +} + +public abstract interface class io/sentry/kotlin/multiplatform/SpanContext { + public abstract fun getDescription ()Ljava/lang/String; + public abstract fun getOperation ()Ljava/lang/String; + public abstract fun getParentSpanId ()Lio/sentry/kotlin/multiplatform/protocol/SpanId; + public abstract fun getSampled ()Z + public abstract fun getSpanId ()Lio/sentry/kotlin/multiplatform/protocol/SpanId; + public abstract fun getTraceId ()Lio/sentry/kotlin/multiplatform/protocol/SentryId; +} + +public final class io/sentry/kotlin/multiplatform/SpanStatus : java/lang/Enum { + public static final field ABORTED Lio/sentry/kotlin/multiplatform/SpanStatus; + public static final field ALREADY_EXISTS Lio/sentry/kotlin/multiplatform/SpanStatus; + public static final field CANCELLED Lio/sentry/kotlin/multiplatform/SpanStatus; + public static final field Companion Lio/sentry/kotlin/multiplatform/SpanStatus$Companion; + public static final field DATA_LOSS Lio/sentry/kotlin/multiplatform/SpanStatus; + public static final field DEADLINE_EXCEEDED Lio/sentry/kotlin/multiplatform/SpanStatus; + public static final field FAILED_PRECONDITION Lio/sentry/kotlin/multiplatform/SpanStatus; + public static final field INTERNAL_ERROR Lio/sentry/kotlin/multiplatform/SpanStatus; + public static final field INVALID_ARGUMENT Lio/sentry/kotlin/multiplatform/SpanStatus; + public static final field NOT_FOUND Lio/sentry/kotlin/multiplatform/SpanStatus; + public static final field OK Lio/sentry/kotlin/multiplatform/SpanStatus; + public static final field OUT_OF_RANGE Lio/sentry/kotlin/multiplatform/SpanStatus; + public static final field PERMISSION_DENIED Lio/sentry/kotlin/multiplatform/SpanStatus; + public static final field RESOURCE_EXHAUSTED Lio/sentry/kotlin/multiplatform/SpanStatus; + public static final field UNAUTHENTICATED Lio/sentry/kotlin/multiplatform/SpanStatus; + public static final field UNAVAILABLE Lio/sentry/kotlin/multiplatform/SpanStatus; + public static final field UNIMPLEMENTED Lio/sentry/kotlin/multiplatform/SpanStatus; + public static final field UNKNOWN Lio/sentry/kotlin/multiplatform/SpanStatus; + public static final field UNKNOWN_ERROR Lio/sentry/kotlin/multiplatform/SpanStatus; + public static fun valueOf (Ljava/lang/String;)Lio/sentry/kotlin/multiplatform/SpanStatus; + public static fun values ()[Lio/sentry/kotlin/multiplatform/SpanStatus; +} + +public final class io/sentry/kotlin/multiplatform/SpanStatus$Companion { + public final fun fromHttpStatusCode (I)Lio/sentry/kotlin/multiplatform/SpanStatus; + public final fun fromHttpStatusCode (Ljava/lang/Integer;Lio/sentry/kotlin/multiplatform/SpanStatus;)Lio/sentry/kotlin/multiplatform/SpanStatus; +} + +public abstract interface class io/sentry/kotlin/multiplatform/TransactionContext : io/sentry/kotlin/multiplatform/SpanContext { + public abstract fun getName ()Ljava/lang/String; + public abstract fun getParentSampled ()Z + public abstract fun getTransactionNameSource ()Lio/sentry/kotlin/multiplatform/protocol/TransactionNameSource; } public final class io/sentry/kotlin/multiplatform/protocol/Breadcrumb { @@ -323,6 +410,33 @@ public final class io/sentry/kotlin/multiplatform/protocol/SentryId$Companion { public final fun getEMPTY_ID ()Lio/sentry/kotlin/multiplatform/protocol/SentryId; } +public final class io/sentry/kotlin/multiplatform/protocol/SpanId { + public static final field Companion Lio/sentry/kotlin/multiplatform/protocol/SpanId$Companion; + public fun (Ljava/lang/String;)V + public final fun component1 ()Ljava/lang/String; + public final fun copy (Ljava/lang/String;)Lio/sentry/kotlin/multiplatform/protocol/SpanId; + public static synthetic fun copy$default (Lio/sentry/kotlin/multiplatform/protocol/SpanId;Ljava/lang/String;ILjava/lang/Object;)Lio/sentry/kotlin/multiplatform/protocol/SpanId; + public fun equals (Ljava/lang/Object;)Z + public final fun getSpanIdString ()Ljava/lang/String; + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public final class io/sentry/kotlin/multiplatform/protocol/SpanId$Companion { + public final fun getEMPTY_ID ()Lio/sentry/kotlin/multiplatform/protocol/SpanId; +} + +public final class io/sentry/kotlin/multiplatform/protocol/TransactionNameSource : java/lang/Enum { + public static final field COMPONENT Lio/sentry/kotlin/multiplatform/protocol/TransactionNameSource; + public static final field CUSTOM Lio/sentry/kotlin/multiplatform/protocol/TransactionNameSource; + public static final field ROUTE Lio/sentry/kotlin/multiplatform/protocol/TransactionNameSource; + public static final field TASK Lio/sentry/kotlin/multiplatform/protocol/TransactionNameSource; + public static final field URL Lio/sentry/kotlin/multiplatform/protocol/TransactionNameSource; + public static final field VIEW Lio/sentry/kotlin/multiplatform/protocol/TransactionNameSource; + public static fun valueOf (Ljava/lang/String;)Lio/sentry/kotlin/multiplatform/protocol/TransactionNameSource; + public static fun values ()[Lio/sentry/kotlin/multiplatform/protocol/TransactionNameSource; +} + public final class io/sentry/kotlin/multiplatform/protocol/User { public fun ()V public fun (Lio/sentry/kotlin/multiplatform/protocol/User;)V From a29e638861c53bedc14a1ee8d53c3a4ff167ef4e Mon Sep 17 00:00:00 2001 From: GIancarlo Buenaflor Date: Thu, 23 Nov 2023 16:11:00 +0100 Subject: [PATCH 25/43] Fix tests --- .../kotlin/io/sentry/kotlin/multiplatform/BaseSentryTest.kt | 1 + .../kotlin/io/sentry/kotlin/multiplatform/SpanTest.kt | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/BaseSentryTest.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/BaseSentryTest.kt index a23652f5..650a474f 100644 --- a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/BaseSentryTest.kt +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/BaseSentryTest.kt @@ -1,5 +1,6 @@ package io.sentry.kotlin.multiplatform +/** Base class for tests where Sentry.init is required. */ expect abstract class BaseSentryTest() { val platform: String val authToken: String? diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SpanTest.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SpanTest.kt index 0af2230f..839fb34b 100644 --- a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SpanTest.kt +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SpanTest.kt @@ -6,7 +6,7 @@ import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertNull -class SpanTest { +class SpanTest : BaseSentryTest() { class Fixture { private val operation = "test" private val description = "test description" From 816f2df1a893592ce2adfddf95799b615237903a Mon Sep 17 00:00:00 2001 From: GIancarlo Buenaflor Date: Thu, 23 Nov 2023 17:59:12 +0100 Subject: [PATCH 26/43] Fix sample --- sentry-samples/kmp-app-cocoapods/shared/build.gradle.kts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/sentry-samples/kmp-app-cocoapods/shared/build.gradle.kts b/sentry-samples/kmp-app-cocoapods/shared/build.gradle.kts index 3f4394e1..62c8d78b 100644 --- a/sentry-samples/kmp-app-cocoapods/shared/build.gradle.kts +++ b/sentry-samples/kmp-app-cocoapods/shared/build.gradle.kts @@ -68,10 +68,9 @@ kotlin { } android { - compileSdk = 32 + compileSdk = Config.Android.compileSdkVersion sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml") defaultConfig { - minSdk = 27 - targetSdk = 32 + minSdk = Config.Android.minSdkVersion } -} +} \ No newline at end of file From 21dcc4b41a3bb69bd426c79a3c76829ed933b385 Mon Sep 17 00:00:00 2001 From: Sentry Github Bot Date: Thu, 23 Nov 2023 17:00:20 +0000 Subject: [PATCH 27/43] Format code --- sentry-samples/kmp-app-cocoapods/shared/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sentry-samples/kmp-app-cocoapods/shared/build.gradle.kts b/sentry-samples/kmp-app-cocoapods/shared/build.gradle.kts index 62c8d78b..bf3a33e2 100644 --- a/sentry-samples/kmp-app-cocoapods/shared/build.gradle.kts +++ b/sentry-samples/kmp-app-cocoapods/shared/build.gradle.kts @@ -73,4 +73,4 @@ android { defaultConfig { minSdk = Config.Android.minSdkVersion } -} \ No newline at end of file +} From 46dc59483c0aca41b3af7e176556b35130bb9570 Mon Sep 17 00:00:00 2001 From: GIancarlo Buenaflor Date: Thu, 23 Nov 2023 18:10:10 +0100 Subject: [PATCH 28/43] Formatting --- .../kotlin/io/sentry/kotlin/multiplatform/UserFeedbackTest.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/UserFeedbackTest.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/UserFeedbackTest.kt index c6b09de3..e1ce35ad 100644 --- a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/UserFeedbackTest.kt +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/UserFeedbackTest.kt @@ -6,7 +6,6 @@ import kotlin.test.Test import kotlin.test.assertEquals class UserFeedbackTest { - private val sentryIdString = "dcebada57d794590a6da3d1977eed58a" @Test From 3869b4be368707721a2458d8a41d87fb4692efc4 Mon Sep 17 00:00:00 2001 From: GIancarlo Buenaflor Date: Thu, 23 Nov 2023 19:22:57 +0100 Subject: [PATCH 29/43] Remove instrumenter --- .../api/android/sentry-kotlin-multiplatform.api | 7 ------- .../api/jvm/sentry-kotlin-multiplatform.api | 7 ------- .../io/sentry/kotlin/multiplatform/Instrumenter.kt | 12 ------------ 3 files changed, 26 deletions(-) delete mode 100644 sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Instrumenter.kt diff --git a/sentry-kotlin-multiplatform/api/android/sentry-kotlin-multiplatform.api b/sentry-kotlin-multiplatform/api/android/sentry-kotlin-multiplatform.api index 81393cf9..977a8b2f 100644 --- a/sentry-kotlin-multiplatform/api/android/sentry-kotlin-multiplatform.api +++ b/sentry-kotlin-multiplatform/api/android/sentry-kotlin-multiplatform.api @@ -45,13 +45,6 @@ public final class io/sentry/kotlin/multiplatform/HttpStatusCodeRange { public final class io/sentry/kotlin/multiplatform/HttpStatusCodeRange$Companion { } -public final class io/sentry/kotlin/multiplatform/Instrumenter : java/lang/Enum { - public static final field OTEL Lio/sentry/kotlin/multiplatform/Instrumenter; - public static final field SENTRY Lio/sentry/kotlin/multiplatform/Instrumenter; - public static fun valueOf (Ljava/lang/String;)Lio/sentry/kotlin/multiplatform/Instrumenter; - public static fun values ()[Lio/sentry/kotlin/multiplatform/Instrumenter; -} - public final class io/sentry/kotlin/multiplatform/SamplingContext { public fun (Lio/sentry/kotlin/multiplatform/TransactionContext;)V public final fun component1 ()Lio/sentry/kotlin/multiplatform/TransactionContext; diff --git a/sentry-kotlin-multiplatform/api/jvm/sentry-kotlin-multiplatform.api b/sentry-kotlin-multiplatform/api/jvm/sentry-kotlin-multiplatform.api index 6940da51..7dc46e84 100644 --- a/sentry-kotlin-multiplatform/api/jvm/sentry-kotlin-multiplatform.api +++ b/sentry-kotlin-multiplatform/api/jvm/sentry-kotlin-multiplatform.api @@ -42,13 +42,6 @@ public final class io/sentry/kotlin/multiplatform/HttpStatusCodeRange { public final class io/sentry/kotlin/multiplatform/HttpStatusCodeRange$Companion { } -public final class io/sentry/kotlin/multiplatform/Instrumenter : java/lang/Enum { - public static final field OTEL Lio/sentry/kotlin/multiplatform/Instrumenter; - public static final field SENTRY Lio/sentry/kotlin/multiplatform/Instrumenter; - public static fun valueOf (Ljava/lang/String;)Lio/sentry/kotlin/multiplatform/Instrumenter; - public static fun values ()[Lio/sentry/kotlin/multiplatform/Instrumenter; -} - public final class io/sentry/kotlin/multiplatform/SamplingContext { public fun (Lio/sentry/kotlin/multiplatform/TransactionContext;)V public final fun component1 ()Lio/sentry/kotlin/multiplatform/TransactionContext; diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Instrumenter.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Instrumenter.kt deleted file mode 100644 index 80910c7c..00000000 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Instrumenter.kt +++ /dev/null @@ -1,12 +0,0 @@ -package io.sentry.kotlin.multiplatform - -/** - * Which framework is responsible for instrumenting. This includes starting and stopping of - * transactions and spans. - */ -public enum class Instrumenter { - SENTRY, - - /** OpenTelemetry */ - OTEL -} From 645d4b14aff8ee9b2ce4f9823e207c96325b5cfd Mon Sep 17 00:00:00 2001 From: GIancarlo Buenaflor Date: Thu, 23 Nov 2023 21:17:47 +0100 Subject: [PATCH 30/43] Format --- .../multiplatform/SentryBridge.apple.kt | 25 ++++++++++++++++ .../multiplatform/SpanProvider.apple.kt | 2 +- .../TransactionContextProvider.apple.kt | 2 +- .../kotlin/multiplatform/TypeAliases.apple.kt | 1 + .../CustomSamplingContextConverters.apple.kt | 7 +++++ .../TransactionContextConverters.apple.kt | 20 +++++++++++++ .../TransactionNameSourceConverters.apple.kt} | 2 +- .../SentryOptionsExtensions.apple.kt | 11 +++---- .../kotlin/multiplatform/SentryBridge.jvm.kt | 25 ++++++++++++++++ .../kotlin/multiplatform/SpanProvider.jvm.kt | 4 +-- .../TransactionContextProvider.jvm.kt | 2 +- .../kotlin/multiplatform/TypeAliases.jvm.kt | 2 ++ .../CustomSamplingContextConverters.jvm.kt | 11 +++++++ .../TransactionContextConverters.jvm.kt | 20 +++++++++++++ .../TransactionNameSourceConverters.jvm.kt} | 2 +- .../extensions/SentryOptionsExtensions.jvm.kt | 4 +-- .../kotlin/multiplatform/SamplingContext.kt | 5 +++- .../kotlin/multiplatform/SentryBridge.kt | 4 +++ .../kotlin/multiplatform/SpanContext.kt | 2 +- .../multiplatform/TransactionContext.kt | 29 +++++++++++++++++-- 20 files changed, 161 insertions(+), 19 deletions(-) create mode 100644 sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/converters/CustomSamplingContextConverters.apple.kt create mode 100644 sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/converters/TransactionContextConverters.apple.kt rename sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/{extensions/TransactionNameSourceExtensions.apple.kt => converters/TransactionNameSourceConverters.apple.kt} (95%) create mode 100644 sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/converters/CustomSamplingContextConverters.jvm.kt create mode 100644 sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/converters/TransactionContextConverters.jvm.kt rename sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/{extensions/TransactionNameSourceExtensions.jvm.kt => converters/TransactionNameSourceConverters.jvm.kt} (92%) diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.apple.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.apple.kt index e7049379..82902756 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.apple.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.apple.kt @@ -1,6 +1,7 @@ package io.sentry.kotlin.multiplatform import cocoapods.Sentry.SentrySDK +import io.sentry.kotlin.multiplatform.converters.toCocoa import io.sentry.kotlin.multiplatform.extensions.toCocoaBreadcrumb import io.sentry.kotlin.multiplatform.extensions.toCocoaUser import io.sentry.kotlin.multiplatform.extensions.toCocoaUserFeedback @@ -74,6 +75,30 @@ internal actual object SentryBridge { return SpanProvider(cocoaSpan) } + actual fun startTransaction( + transactionContext: TransactionContext, + customSamplingContext: Map? + ): Span { + val cocoaSpan = SentrySDK.startTransactionWithContext( + transactionContext.toCocoa(), + customSamplingContext?.toCocoa() ?: mapOf() + ) + return SpanProvider(cocoaSpan) + } + + actual fun startTransaction( + transactionContext: TransactionContext, + customSamplingContext: Map?, + bindToScope: Boolean + ): Span { + val cocoaSpan = SentrySDK.startTransactionWithContext( + transactionContext.toCocoa(), + bindToScope, + customSamplingContext?.toCocoa() ?: mapOf() + ) + return SpanProvider(cocoaSpan) + } + actual fun getSpan(): Span? { val cocoaSpan = SentrySDK.span return cocoaSpan?.let { SpanProvider(it) } diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SpanProvider.apple.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SpanProvider.apple.kt index 220e239f..adfa01c7 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SpanProvider.apple.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SpanProvider.apple.kt @@ -1,7 +1,7 @@ package io.sentry.kotlin.multiplatform import cocoapods.Sentry.SentrySpanProtocol -import io.sentry.kotlin.multiplatform.extensions.toCocoa +import io.sentry.kotlin.multiplatform.converters.toCocoa import io.sentry.kotlin.multiplatform.extensions.toKmp import io.sentry.kotlin.multiplatform.protocol.SpanId diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContextProvider.apple.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContextProvider.apple.kt index ec5651bf..dd2a1c8b 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContextProvider.apple.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContextProvider.apple.kt @@ -1,7 +1,7 @@ package io.sentry.kotlin.multiplatform +import io.sentry.kotlin.multiplatform.converters.toKmpTransactionNameSource import io.sentry.kotlin.multiplatform.extensions.toBoolean -import io.sentry.kotlin.multiplatform.extensions.toKmpTransactionNameSource import io.sentry.kotlin.multiplatform.protocol.SentryId import io.sentry.kotlin.multiplatform.protocol.SpanId import io.sentry.kotlin.multiplatform.protocol.TransactionNameSource diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/TypeAliases.apple.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/TypeAliases.apple.kt index 8713f8bf..2da4295b 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/TypeAliases.apple.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/TypeAliases.apple.kt @@ -31,3 +31,4 @@ internal typealias CocoaSpanStatus = SentrySpanStatus internal typealias CocoaSpanId = SentrySpanId internal typealias CocoaTransactionContext = SentryTransactionContext internal typealias CocoaSampleDecision = SentrySampleDecision +internal typealias CocoaCustomSamplingContext = Map diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/converters/CustomSamplingContextConverters.apple.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/converters/CustomSamplingContextConverters.apple.kt new file mode 100644 index 00000000..b4799ba9 --- /dev/null +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/converters/CustomSamplingContextConverters.apple.kt @@ -0,0 +1,7 @@ +package io.sentry.kotlin.multiplatform.converters + +import io.sentry.kotlin.multiplatform.CocoaCustomSamplingContext + +internal fun Map.toCocoa(): CocoaCustomSamplingContext { + return this as CocoaCustomSamplingContext +} diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/converters/TransactionContextConverters.apple.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/converters/TransactionContextConverters.apple.kt new file mode 100644 index 00000000..0ea8fa91 --- /dev/null +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/converters/TransactionContextConverters.apple.kt @@ -0,0 +1,20 @@ +package io.sentry.kotlin.multiplatform.converters + +import io.sentry.kotlin.multiplatform.CocoaSampleDecision +import io.sentry.kotlin.multiplatform.CocoaTransactionContext +import io.sentry.kotlin.multiplatform.TransactionContext +import io.sentry.kotlin.multiplatform.extensions.toSampleDecision + +/** + * Converts a [CocoaTransactionContext] to a [TransactionContext]. + * + * Mainly used by the SDK for starting transactions with a [TransactionContext]. + */ +internal fun TransactionContext.toCocoa(): CocoaTransactionContext { + val sampleDecision = sampled?.toSampleDecision() ?: CocoaSampleDecision.kSentrySampleDecisionUndecided + val kmpScope = this@toCocoa + + return CocoaTransactionContext(name, operation, sampleDecision).apply { + parentSampled = kmpScope.parentSampled.toSampleDecision() + } +} diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/TransactionNameSourceExtensions.apple.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/converters/TransactionNameSourceConverters.apple.kt similarity index 95% rename from sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/TransactionNameSourceExtensions.apple.kt rename to sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/converters/TransactionNameSourceConverters.apple.kt index f476d3b9..2ae0c54c 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/TransactionNameSourceExtensions.apple.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/converters/TransactionNameSourceConverters.apple.kt @@ -1,4 +1,4 @@ -package io.sentry.kotlin.multiplatform.extensions +package io.sentry.kotlin.multiplatform.converters import io.sentry.kotlin.multiplatform.protocol.TransactionNameSource import kotlinx.cinterop.UnsafeNumber diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.apple.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.apple.kt index 775279d6..572a93ff 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.apple.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.apple.kt @@ -8,7 +8,6 @@ import io.sentry.kotlin.multiplatform.CocoaSentryOptions import io.sentry.kotlin.multiplatform.SamplingContext import io.sentry.kotlin.multiplatform.SentryEvent import io.sentry.kotlin.multiplatform.SentryOptions -import io.sentry.kotlin.multiplatform.TransactionContextAdapter import io.sentry.kotlin.multiplatform.TransactionContextProvider import io.sentry.kotlin.multiplatform.nsexception.dropKotlinCrashEvent import kotlinx.cinterop.convert @@ -86,12 +85,14 @@ internal fun CocoaSentryOptions.applyCocoaBaseOptions(options: SentryOptions) { } } - tracesSampler = { - it?.let { context -> + tracesSampler = { cocoaSamplingContext -> + cocoaSamplingContext?.let { context -> + val customSamplingContext: Map? = context.customSamplingContext?.mapKeys { entry -> + entry.key.toString() + } val cocoaTransactionContext = TransactionContextProvider(context.transactionContext) - val transactionContext = TransactionContextAdapter(cocoaTransactionContext) - val samplingContext = SamplingContext(transactionContext) + val samplingContext = SamplingContext(cocoaTransactionContext, customSamplingContext) // returns null if KMP tracesSampler is null val sampleRate = options.tracesSampler?.invoke(samplingContext) sampleRate?.let { unwrappedSampleRate -> diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.jvm.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.jvm.kt index 089c7efc..85df871d 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.jvm.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.jvm.kt @@ -1,6 +1,8 @@ package io.sentry.kotlin.multiplatform +import io.sentry.CustomSamplingContext import io.sentry.Sentry +import io.sentry.kotlin.multiplatform.converters.toJvm import io.sentry.kotlin.multiplatform.extensions.toJvmBreadcrumb import io.sentry.kotlin.multiplatform.extensions.toJvmUser import io.sentry.kotlin.multiplatform.extensions.toJvmUserFeedback @@ -67,6 +69,29 @@ internal actual object SentryBridge { return SpanProvider(jvmTransaction) } + actual fun startTransaction( + transactionContext: TransactionContext, + customSamplingContext: Map? + ): Span { + val jvmCustomSamplingContext = customSamplingContext?.toJvm() ?: CustomSamplingContext() + val jvmTransactionContext = transactionContext.toJvm() + val jvmTransaction = + Sentry.startTransaction(jvmTransactionContext, jvmCustomSamplingContext) + return SpanProvider(jvmTransaction) + } + + actual fun startTransaction( + transactionContext: TransactionContext, + customSamplingContext: Map?, + bindToScope: Boolean + ): Span { + val jvmCustomSamplingContext = customSamplingContext?.toJvm() + val jvmTransactionContext = transactionContext.toJvm() + val jvmTransaction = + Sentry.startTransaction(jvmTransactionContext, jvmCustomSamplingContext, bindToScope) + return SpanProvider(jvmTransaction) + } + actual fun getSpan(): Span? { val jvmSpan = Sentry.getSpan() return jvmSpan?.let { SpanProvider(it) } diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SpanProvider.jvm.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SpanProvider.jvm.kt index 310f48f6..87142150 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SpanProvider.jvm.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SpanProvider.jvm.kt @@ -1,8 +1,8 @@ package io.sentry.kotlin.multiplatform import io.sentry.ISpan -import io.sentry.kotlin.multiplatform.extensions.toJvm -import io.sentry.kotlin.multiplatform.extensions.toKmp +import io.sentry.kotlin.multiplatform.converters.toJvm +import io.sentry.kotlin.multiplatform.converters.toKmp import io.sentry.kotlin.multiplatform.protocol.SpanId internal class SpanProvider(private val jvmSpan: ISpan) : Span { diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContextProvider.jvm.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContextProvider.jvm.kt index d83975e1..1b9ab1dd 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContextProvider.jvm.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContextProvider.jvm.kt @@ -1,6 +1,6 @@ package io.sentry.kotlin.multiplatform -import io.sentry.kotlin.multiplatform.extensions.toKmp +import io.sentry.kotlin.multiplatform.converters.toKmp import io.sentry.kotlin.multiplatform.protocol.SentryId import io.sentry.kotlin.multiplatform.protocol.SpanId import io.sentry.kotlin.multiplatform.protocol.TransactionNameSource diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/TypeAliases.jvm.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/TypeAliases.jvm.kt index e29ea786..5be1cade 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/TypeAliases.jvm.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/TypeAliases.jvm.kt @@ -2,6 +2,7 @@ package io.sentry.kotlin.multiplatform import io.sentry.Attachment import io.sentry.Breadcrumb +import io.sentry.CustomSamplingContext import io.sentry.Scope import io.sentry.SentryEvent import io.sentry.SentryLevel @@ -33,3 +34,4 @@ internal typealias JvmSpanStatus = SpanStatus internal typealias JvmSpanId = SpanId internal typealias JvmTransactionContext = TransactionContext internal typealias JvmTransactionNameSource = TransactionNameSource +internal typealias JvmCustomSamplingContext = CustomSamplingContext diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/converters/CustomSamplingContextConverters.jvm.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/converters/CustomSamplingContextConverters.jvm.kt new file mode 100644 index 00000000..5024b24c --- /dev/null +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/converters/CustomSamplingContextConverters.jvm.kt @@ -0,0 +1,11 @@ +package io.sentry.kotlin.multiplatform.converters + +import io.sentry.kotlin.multiplatform.JvmCustomSamplingContext + +internal fun Map.toJvm(): JvmCustomSamplingContext { + val jvmCustomSamplingContext = JvmCustomSamplingContext() + forEach { (key, value) -> + jvmCustomSamplingContext[key] = value + } + return jvmCustomSamplingContext +} diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/converters/TransactionContextConverters.jvm.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/converters/TransactionContextConverters.jvm.kt new file mode 100644 index 00000000..af9e1e60 --- /dev/null +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/converters/TransactionContextConverters.jvm.kt @@ -0,0 +1,20 @@ +package io.sentry.kotlin.multiplatform.converters + +import io.sentry.TracesSamplingDecision +import io.sentry.kotlin.multiplatform.JvmTransactionContext +import io.sentry.kotlin.multiplatform.TransactionContext + +/** + * Converts a [JvmTransactionContext] to a [TransactionContext]. + * + * Mainly used by the SDK for starting transactions with a [TransactionContext]. + */ +internal fun TransactionContext.toJvm(): JvmTransactionContext { + val sampleDecision = sampled?.let { TracesSamplingDecision(it) } + val kmpScope = this@toJvm + return JvmTransactionContext(name, operation, sampleDecision).apply { + parentSampled = kmpScope.parentSampled + description = kmpScope.description + name = kmpScope.name + } +} diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/TransactionNameSourceExtensions.jvm.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/converters/TransactionNameSourceConverters.jvm.kt similarity index 92% rename from sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/TransactionNameSourceExtensions.jvm.kt rename to sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/converters/TransactionNameSourceConverters.jvm.kt index 4c15dfc6..66f81431 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/TransactionNameSourceExtensions.jvm.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/converters/TransactionNameSourceConverters.jvm.kt @@ -1,4 +1,4 @@ -package io.sentry.kotlin.multiplatform.extensions +package io.sentry.kotlin.multiplatform.converters import io.sentry.kotlin.multiplatform.JvmTransactionNameSource import io.sentry.kotlin.multiplatform.protocol.TransactionNameSource diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.jvm.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.jvm.kt index d36da0eb..aad2fb5b 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.jvm.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.jvm.kt @@ -5,7 +5,6 @@ import io.sentry.kotlin.multiplatform.JvmSentryOptions import io.sentry.kotlin.multiplatform.SamplingContext import io.sentry.kotlin.multiplatform.SentryEvent import io.sentry.kotlin.multiplatform.SentryOptions -import io.sentry.kotlin.multiplatform.TransactionContextAdapter import io.sentry.kotlin.multiplatform.TransactionContextProvider internal fun SentryOptions.toJvmSentryOptionsCallback(): (JvmSentryOptions) -> Unit = { @@ -64,8 +63,7 @@ internal fun JvmSentryOptions.applyJvmBaseOptions(options: SentryOptions) { } setTracesSampler { jvmSamplingContext -> val jvmTransactionContext = TransactionContextProvider(jvmSamplingContext.transactionContext) - val transactionContext = TransactionContextAdapter(jvmTransactionContext) - val samplingContext = SamplingContext(transactionContext) + val samplingContext = SamplingContext(jvmTransactionContext, jvmSamplingContext.customSamplingContext?.data) // returns null if KMP tracesSampler is null val sampleRate = options.tracesSampler?.invoke(samplingContext) sampleRate diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SamplingContext.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SamplingContext.kt index 1d6d8ea8..55da0255 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SamplingContext.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SamplingContext.kt @@ -6,5 +6,8 @@ package io.sentry.kotlin.multiplatform */ public data class SamplingContext( /** The transaction context. */ - public val transactionContext: TransactionContext + public val transactionContext: TransactionContext, + + /** Arbitrary data used to determine if transaction is going to be sampled. */ + public val customSamplingContext: Map? ) diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt index 611190da..752a0c41 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt @@ -31,6 +31,10 @@ internal expect object SentryBridge { fun startTransaction(name: String, operation: String, bindToScope: Boolean): Span + fun startTransaction(transactionContext: TransactionContext, customSamplingContext: Map?): Span + + fun startTransaction(transactionContext: TransactionContext, customSamplingContext: Map?, bindToScope: Boolean): Span + fun getSpan(): Span? fun close() diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SpanContext.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SpanContext.kt index c2419c5a..75aaf9a7 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SpanContext.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SpanContext.kt @@ -22,5 +22,5 @@ public interface SpanContext { public val description: String? /** Indicates if the span is sampled.*/ - public val sampled: Boolean + public val sampled: Boolean? } diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContext.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContext.kt index 81e423e9..87270f96 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContext.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContext.kt @@ -1,5 +1,7 @@ package io.sentry.kotlin.multiplatform +import io.sentry.kotlin.multiplatform.protocol.SentryId +import io.sentry.kotlin.multiplatform.protocol.SpanId import io.sentry.kotlin.multiplatform.protocol.TransactionNameSource /** The Transaction Context defines the metadata for a Performance Monitoring Transaction. */ @@ -14,5 +16,28 @@ public interface TransactionContext : SpanContext { public val parentSampled: Boolean } -internal class TransactionContextAdapter constructor(private val transactionContext: TransactionContext) : - TransactionContext by transactionContext +public fun TransactionContext(operation: String): TransactionContext = TransactionContextImpl(operation) +public fun TransactionContext(operation: String, name: String): TransactionContext = + TransactionContextImpl(operation, name) +public fun TransactionContext(operation: String, name: String, sampled: Boolean): TransactionContext = + TransactionContextImpl(operation, name, sampled) + +public class TransactionContextImpl(override val operation: String) : TransactionContext { + override var name: String = "" + override var sampled: Boolean? = null + override var parentSampled: Boolean = false + override var traceId: SentryId = SentryId.EMPTY_ID + override var spanId: SpanId = SpanId.EMPTY_ID + override var parentSpanId: SpanId? = null + override var description: String? = null + override var transactionNameSource: TransactionNameSource = TransactionNameSource.CUSTOM + + public constructor(operation: String, name: String) : this(operation) { + this.name = name + } + + public constructor(operation: String, name: String, sampled: Boolean?) : this(operation, name) { + this.name = name + this.sampled = sampled + } +} From b1c3b4e8822c820093b40e80ca29fceae046faf0 Mon Sep 17 00:00:00 2001 From: GIancarlo Buenaflor Date: Fri, 24 Nov 2023 12:16:36 +0100 Subject: [PATCH 31/43] Add more startTransaction methods --- config/detekt/detekt.yml | 2 +- .../kotlin/multiplatform/SpanProvider.apple.kt | 2 +- .../sentry/kotlin/multiplatform/SpanProvider.jvm.kt | 4 ++-- .../io/sentry/kotlin/multiplatform/SentryBridge.kt | 13 ++++++++++--- .../kotlin/multiplatform/TransactionContext.kt | 13 +++++++------ 5 files changed, 21 insertions(+), 13 deletions(-) diff --git a/config/detekt/detekt.yml b/config/detekt/detekt.yml index 53a4a87d..15d6f6ab 100644 --- a/config/detekt/detekt.yml +++ b/config/detekt/detekt.yml @@ -16,7 +16,7 @@ style: MagicNumber: excludes: - "**/SpanStatus.*" - - "**/TransactionNameSourceExtensions.*" + - "**/TransactionNameSource*" naming: MatchingDeclarationName: active: false diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SpanProvider.apple.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SpanProvider.apple.kt index adfa01c7..220e239f 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SpanProvider.apple.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SpanProvider.apple.kt @@ -1,7 +1,7 @@ package io.sentry.kotlin.multiplatform import cocoapods.Sentry.SentrySpanProtocol -import io.sentry.kotlin.multiplatform.converters.toCocoa +import io.sentry.kotlin.multiplatform.extensions.toCocoa import io.sentry.kotlin.multiplatform.extensions.toKmp import io.sentry.kotlin.multiplatform.protocol.SpanId diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SpanProvider.jvm.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SpanProvider.jvm.kt index 87142150..310f48f6 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SpanProvider.jvm.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SpanProvider.jvm.kt @@ -1,8 +1,8 @@ package io.sentry.kotlin.multiplatform import io.sentry.ISpan -import io.sentry.kotlin.multiplatform.converters.toJvm -import io.sentry.kotlin.multiplatform.converters.toKmp +import io.sentry.kotlin.multiplatform.extensions.toJvm +import io.sentry.kotlin.multiplatform.extensions.toKmp import io.sentry.kotlin.multiplatform.protocol.SpanId internal class SpanProvider(private val jvmSpan: ISpan) : Span { diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt index 752a0c41..414dd15c 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt @@ -31,9 +31,16 @@ internal expect object SentryBridge { fun startTransaction(name: String, operation: String, bindToScope: Boolean): Span - fun startTransaction(transactionContext: TransactionContext, customSamplingContext: Map?): Span - - fun startTransaction(transactionContext: TransactionContext, customSamplingContext: Map?, bindToScope: Boolean): Span + fun startTransaction( + transactionContext: TransactionContext, + customSamplingContext: Map? + ): Span + + fun startTransaction( + transactionContext: TransactionContext, + customSamplingContext: Map?, + bindToScope: Boolean + ): Span fun getSpan(): Span? diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContext.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContext.kt index 87270f96..25c405f3 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContext.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContext.kt @@ -16,12 +16,7 @@ public interface TransactionContext : SpanContext { public val parentSampled: Boolean } -public fun TransactionContext(operation: String): TransactionContext = TransactionContextImpl(operation) -public fun TransactionContext(operation: String, name: String): TransactionContext = - TransactionContextImpl(operation, name) -public fun TransactionContext(operation: String, name: String, sampled: Boolean): TransactionContext = - TransactionContextImpl(operation, name, sampled) - +/** The default Transaction Context implementation. */ public class TransactionContextImpl(override val operation: String) : TransactionContext { override var name: String = "" override var sampled: Boolean? = null @@ -41,3 +36,9 @@ public class TransactionContextImpl(override val operation: String) : Transactio this.sampled = sampled } } + +public fun TransactionContext(operation: String): TransactionContext = TransactionContextImpl(operation) +public fun TransactionContext(operation: String, name: String): TransactionContext = + TransactionContextImpl(operation, name) +public fun TransactionContext(operation: String, name: String, sampled: Boolean): TransactionContext = + TransactionContextImpl(operation, name, sampled) From 41a4d4b3e733f9c99c71519c2eb4855aee60ef02 Mon Sep 17 00:00:00 2001 From: GIancarlo Buenaflor Date: Fri, 24 Nov 2023 15:10:23 +0100 Subject: [PATCH 32/43] Update tests --- config/detekt/detekt.yml | 8 +- .../multiplatform/SentryBridge.apple.kt | 4 +- .../multiplatform/SpanProvider.apple.kt | 4 +- .../TransactionContextProvider.apple.kt | 6 +- .../CustomSamplingContextConverters.apple.kt | 3 +- .../SentrySampleDecisionConverters.apple.kt} | 10 +- .../SpanStatusConverters.apple.kt} | 2 +- .../TransactionContextConverters.apple.kt | 1 - .../SentryOptionsExtensions.apple.kt | 8 +- .../CustomSamplingContextConvertersTest.kt | 22 ++ .../kotlin/multiplatform/SentryBridge.jvm.kt | 6 +- .../kotlin/multiplatform/SpanProvider.jvm.kt | 4 +- .../TransactionContextProvider.jvm.kt | 4 +- .../CustomSamplingContextConverters.jvm.kt | 5 +- .../SpanStatusConverters.jvm.kt} | 2 +- .../kotlin/multiplatform/SamplingContext.kt | 4 +- .../kotlin/multiplatform/SentryBridge.kt | 4 +- .../sentry/kotlin/multiplatform/SentryKMP.kt | 32 ++ .../kotlin/multiplatform/SpanContext.kt | 4 +- .../multiplatform/TransactionContext.kt | 21 +- .../multiplatform/SentryTransactionTest.kt | 349 ++++++++++++++++++ .../sentry/kotlin/multiplatform/SpanTest.kt | 134 ------- ...amplerRateTest.kt => TracesSamplerTest.kt} | 44 ++- .../multiplatform/TransactionContextTest.kt | 186 ++++++++++ ...ctionContext.kt => FakeSamplingContext.kt} | 13 +- 25 files changed, 692 insertions(+), 188 deletions(-) rename sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/{extensions/SentrySampleDecisionExtensions.kt => converters/SentrySampleDecisionConverters.apple.kt} (52%) rename sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/{extensions/SpanStatusExtensions.apple.kt => converters/SpanStatusConverters.apple.kt} (98%) create mode 100644 sentry-kotlin-multiplatform/src/commonAppleTest/kotlin/io/sentry/kotlin/multiplatform/converters/CustomSamplingContextConvertersTest.kt rename sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/{extensions/SpanStatusExtensions.kt => converters/SpanStatusConverters.jvm.kt} (97%) create mode 100644 sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryTransactionTest.kt delete mode 100644 sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SpanTest.kt rename sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/{TracesSamplerRateTest.kt => TracesSamplerTest.kt} (82%) create mode 100644 sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TransactionContextTest.kt rename sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/fakes/{FakeTransactionContext.kt => FakeSamplingContext.kt} (79%) diff --git a/config/detekt/detekt.yml b/config/detekt/detekt.yml index 15d6f6ab..d0cebae4 100644 --- a/config/detekt/detekt.yml +++ b/config/detekt/detekt.yml @@ -15,7 +15,7 @@ style: - "**/Attachment.kt" MagicNumber: excludes: - - "**/SpanStatus.*" + - "**/SpanStatus*" - "**/TransactionNameSource*" naming: MatchingDeclarationName: @@ -31,9 +31,9 @@ complexity: ] LongMethod: excludes: - - "**/SentryOptionsExtensions.*" + - "**/SentryOptions*" CyclomaticComplexMethod: excludes: - - "**/SpanStatusExtensions.*" - - "**/SentryOptionsExtensions.*" + - "**/SpanStatus*" + - "**/SentryOptions*" diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.apple.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.apple.kt index 82902756..9ba4c562 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.apple.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.apple.kt @@ -77,7 +77,7 @@ internal actual object SentryBridge { actual fun startTransaction( transactionContext: TransactionContext, - customSamplingContext: Map? + customSamplingContext: CustomSamplingContext ): Span { val cocoaSpan = SentrySDK.startTransactionWithContext( transactionContext.toCocoa(), @@ -88,7 +88,7 @@ internal actual object SentryBridge { actual fun startTransaction( transactionContext: TransactionContext, - customSamplingContext: Map?, + customSamplingContext: CustomSamplingContext, bindToScope: Boolean ): Span { val cocoaSpan = SentrySDK.startTransactionWithContext( diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SpanProvider.apple.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SpanProvider.apple.kt index 220e239f..e1e4fdeb 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SpanProvider.apple.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/SpanProvider.apple.kt @@ -1,8 +1,8 @@ package io.sentry.kotlin.multiplatform import cocoapods.Sentry.SentrySpanProtocol -import io.sentry.kotlin.multiplatform.extensions.toCocoa -import io.sentry.kotlin.multiplatform.extensions.toKmp +import io.sentry.kotlin.multiplatform.converters.toCocoa +import io.sentry.kotlin.multiplatform.converters.toKmp import io.sentry.kotlin.multiplatform.protocol.SpanId internal class SpanProvider(private val cocoaSpan: SentrySpanProtocol) : Span { diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContextProvider.apple.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContextProvider.apple.kt index dd2a1c8b..0949dd42 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContextProvider.apple.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContextProvider.apple.kt @@ -1,7 +1,7 @@ package io.sentry.kotlin.multiplatform +import io.sentry.kotlin.multiplatform.converters.toBoolean import io.sentry.kotlin.multiplatform.converters.toKmpTransactionNameSource -import io.sentry.kotlin.multiplatform.extensions.toBoolean import io.sentry.kotlin.multiplatform.protocol.SentryId import io.sentry.kotlin.multiplatform.protocol.SpanId import io.sentry.kotlin.multiplatform.protocol.TransactionNameSource @@ -11,8 +11,8 @@ internal class TransactionContextProvider(cocoaTransactionContext: CocoaTransact override val name: String = cocoaTransactionContext.name override val transactionNameSource: TransactionNameSource = cocoaTransactionContext.nameSource.toKmpTransactionNameSource() - override val sampled: Boolean = cocoaTransactionContext.sampled().toBoolean() - override val parentSampled: Boolean = cocoaTransactionContext.parentSampled().toBoolean() + override val sampled: Boolean? = cocoaTransactionContext.sampled().toBoolean() + override val parentSampled: Boolean? = cocoaTransactionContext.parentSampled().toBoolean() override val operation: String = cocoaTransactionContext.operation override val traceId: SentryId = SentryId(cocoaTransactionContext.traceId.toString()) override val spanId: SpanId = SpanId(cocoaTransactionContext.spanId.toString()) diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/converters/CustomSamplingContextConverters.apple.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/converters/CustomSamplingContextConverters.apple.kt index b4799ba9..d2edaabc 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/converters/CustomSamplingContextConverters.apple.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/converters/CustomSamplingContextConverters.apple.kt @@ -1,7 +1,8 @@ package io.sentry.kotlin.multiplatform.converters import io.sentry.kotlin.multiplatform.CocoaCustomSamplingContext +import io.sentry.kotlin.multiplatform.CustomSamplingContext -internal fun Map.toCocoa(): CocoaCustomSamplingContext { +internal fun CustomSamplingContext.toCocoa(): CocoaCustomSamplingContext { return this as CocoaCustomSamplingContext } diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentrySampleDecisionExtensions.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/converters/SentrySampleDecisionConverters.apple.kt similarity index 52% rename from sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentrySampleDecisionExtensions.kt rename to sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/converters/SentrySampleDecisionConverters.apple.kt index d1fd91a7..a2e9b16e 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentrySampleDecisionExtensions.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/converters/SentrySampleDecisionConverters.apple.kt @@ -1,17 +1,17 @@ -package io.sentry.kotlin.multiplatform.extensions +package io.sentry.kotlin.multiplatform.converters import cocoapods.Sentry.SentrySampleDecision -internal fun SentrySampleDecision.toBoolean(): Boolean = when (this) { - SentrySampleDecision.kSentrySampleDecisionNo -> false +internal fun SentrySampleDecision.toBoolean(): Boolean? = when (this) { SentrySampleDecision.kSentrySampleDecisionUndecided -> false SentrySampleDecision.kSentrySampleDecisionYes -> true else -> { - false + null } } -internal fun Boolean.toSampleDecision(): SentrySampleDecision = when (this) { +internal fun Boolean?.toSampleDecision(): SentrySampleDecision = when (this) { + null -> SentrySampleDecision.kSentrySampleDecisionUndecided false -> SentrySampleDecision.kSentrySampleDecisionNo true -> SentrySampleDecision.kSentrySampleDecisionYes } diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SpanStatusExtensions.apple.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/converters/SpanStatusConverters.apple.kt similarity index 98% rename from sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SpanStatusExtensions.apple.kt rename to sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/converters/SpanStatusConverters.apple.kt index d42601cd..cd6e5059 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SpanStatusExtensions.apple.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/converters/SpanStatusConverters.apple.kt @@ -1,4 +1,4 @@ -package io.sentry.kotlin.multiplatform.extensions +package io.sentry.kotlin.multiplatform.converters import io.sentry.kotlin.multiplatform.CocoaSpanStatus import io.sentry.kotlin.multiplatform.SpanStatus diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/converters/TransactionContextConverters.apple.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/converters/TransactionContextConverters.apple.kt index 0ea8fa91..db702e3b 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/converters/TransactionContextConverters.apple.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/converters/TransactionContextConverters.apple.kt @@ -3,7 +3,6 @@ package io.sentry.kotlin.multiplatform.converters import io.sentry.kotlin.multiplatform.CocoaSampleDecision import io.sentry.kotlin.multiplatform.CocoaTransactionContext import io.sentry.kotlin.multiplatform.TransactionContext -import io.sentry.kotlin.multiplatform.extensions.toSampleDecision /** * Converts a [CocoaTransactionContext] to a [TransactionContext]. diff --git a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.apple.kt b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.apple.kt index 572a93ff..4c672602 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.apple.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.apple.kt @@ -5,6 +5,7 @@ import cocoapods.Sentry.SentryHttpStatusCodeRange import io.sentry.kotlin.multiplatform.BuildKonfig import io.sentry.kotlin.multiplatform.CocoaSentryEvent import io.sentry.kotlin.multiplatform.CocoaSentryOptions +import io.sentry.kotlin.multiplatform.CustomSamplingContext import io.sentry.kotlin.multiplatform.SamplingContext import io.sentry.kotlin.multiplatform.SentryEvent import io.sentry.kotlin.multiplatform.SentryOptions @@ -87,9 +88,10 @@ internal fun CocoaSentryOptions.applyCocoaBaseOptions(options: SentryOptions) { tracesSampler = { cocoaSamplingContext -> cocoaSamplingContext?.let { context -> - val customSamplingContext: Map? = context.customSamplingContext?.mapKeys { entry -> - entry.key.toString() - } + val customSamplingContext: CustomSamplingContext = + context.customSamplingContext?.mapKeys { entry -> + entry.key.toString() + } val cocoaTransactionContext = TransactionContextProvider(context.transactionContext) val samplingContext = SamplingContext(cocoaTransactionContext, customSamplingContext) diff --git a/sentry-kotlin-multiplatform/src/commonAppleTest/kotlin/io/sentry/kotlin/multiplatform/converters/CustomSamplingContextConvertersTest.kt b/sentry-kotlin-multiplatform/src/commonAppleTest/kotlin/io/sentry/kotlin/multiplatform/converters/CustomSamplingContextConvertersTest.kt new file mode 100644 index 00000000..a0a73708 --- /dev/null +++ b/sentry-kotlin-multiplatform/src/commonAppleTest/kotlin/io/sentry/kotlin/multiplatform/converters/CustomSamplingContextConvertersTest.kt @@ -0,0 +1,22 @@ +package io.sentry.kotlin.multiplatform.converters + +import io.sentry.kotlin.multiplatform.CocoaCustomSamplingContext +import io.sentry.kotlin.multiplatform.CustomSamplingContext +import io.sentry.kotlin.multiplatform.fakes.createFakeCustomSamplingContext +import kotlin.test.Test +import kotlin.test.assertTrue + +class CustomSamplingContextConvertersTest { + // Test that toCocoa doesn't crash + @Test + fun `GIVEN customSamplingContext WHEN toCocoa called THEN value is CocoaCustomSamplingContext`() { + // GIVEN + val customSamplingContext: CustomSamplingContext = createFakeCustomSamplingContext() + + // WHEN + val cocoaCustomSamplingContext = customSamplingContext.toCocoa() + + // THEN + assertTrue(cocoaCustomSamplingContext is CocoaCustomSamplingContext) + } +} diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.jvm.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.jvm.kt index 85df871d..102403a4 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.jvm.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.jvm.kt @@ -10,11 +10,11 @@ import io.sentry.kotlin.multiplatform.protocol.Breadcrumb import io.sentry.kotlin.multiplatform.protocol.SentryId import io.sentry.kotlin.multiplatform.protocol.User import io.sentry.kotlin.multiplatform.protocol.UserFeedback +import io.sentry.kotlin.multiplatform.CustomSamplingContext as KmpCustomSamplingContext internal expect fun initSentry(configuration: OptionsConfiguration) internal actual object SentryBridge { - actual fun init(context: Context, configuration: OptionsConfiguration) { initSentry(configuration) } @@ -71,7 +71,7 @@ internal actual object SentryBridge { actual fun startTransaction( transactionContext: TransactionContext, - customSamplingContext: Map? + customSamplingContext: KmpCustomSamplingContext ): Span { val jvmCustomSamplingContext = customSamplingContext?.toJvm() ?: CustomSamplingContext() val jvmTransactionContext = transactionContext.toJvm() @@ -82,7 +82,7 @@ internal actual object SentryBridge { actual fun startTransaction( transactionContext: TransactionContext, - customSamplingContext: Map?, + customSamplingContext: KmpCustomSamplingContext, bindToScope: Boolean ): Span { val jvmCustomSamplingContext = customSamplingContext?.toJvm() diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SpanProvider.jvm.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SpanProvider.jvm.kt index 310f48f6..87142150 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SpanProvider.jvm.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SpanProvider.jvm.kt @@ -1,8 +1,8 @@ package io.sentry.kotlin.multiplatform import io.sentry.ISpan -import io.sentry.kotlin.multiplatform.extensions.toJvm -import io.sentry.kotlin.multiplatform.extensions.toKmp +import io.sentry.kotlin.multiplatform.converters.toJvm +import io.sentry.kotlin.multiplatform.converters.toKmp import io.sentry.kotlin.multiplatform.protocol.SpanId internal class SpanProvider(private val jvmSpan: ISpan) : Span { diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContextProvider.jvm.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContextProvider.jvm.kt index 1b9ab1dd..363e9c9a 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContextProvider.jvm.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContextProvider.jvm.kt @@ -10,8 +10,8 @@ internal class TransactionContextProvider(jvmTransactionContext: JvmTransactionC override val name: String = jvmTransactionContext.name override val transactionNameSource: TransactionNameSource = jvmTransactionContext.transactionNameSource.toKmp() - override val sampled: Boolean = jvmTransactionContext.sampled ?: false - override val parentSampled: Boolean = jvmTransactionContext.parentSampled ?: false + override val sampled: Boolean? = jvmTransactionContext.sampled + override val parentSampled: Boolean? = jvmTransactionContext.parentSampled override val operation: String = jvmTransactionContext.operation override val traceId: SentryId = SentryId(jvmTransactionContext.traceId.toString()) override val spanId: SpanId = SpanId(jvmTransactionContext.spanId.toString()) diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/converters/CustomSamplingContextConverters.jvm.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/converters/CustomSamplingContextConverters.jvm.kt index 5024b24c..5090b90d 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/converters/CustomSamplingContextConverters.jvm.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/converters/CustomSamplingContextConverters.jvm.kt @@ -1,10 +1,11 @@ package io.sentry.kotlin.multiplatform.converters +import io.sentry.kotlin.multiplatform.CustomSamplingContext import io.sentry.kotlin.multiplatform.JvmCustomSamplingContext -internal fun Map.toJvm(): JvmCustomSamplingContext { +internal fun CustomSamplingContext.toJvm(): JvmCustomSamplingContext { val jvmCustomSamplingContext = JvmCustomSamplingContext() - forEach { (key, value) -> + this?.forEach { (key, value) -> jvmCustomSamplingContext[key] = value } return jvmCustomSamplingContext diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SpanStatusExtensions.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/converters/SpanStatusConverters.jvm.kt similarity index 97% rename from sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SpanStatusExtensions.kt rename to sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/converters/SpanStatusConverters.jvm.kt index b40e0f75..d81c982f 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SpanStatusExtensions.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/converters/SpanStatusConverters.jvm.kt @@ -1,4 +1,4 @@ -package io.sentry.kotlin.multiplatform.extensions +package io.sentry.kotlin.multiplatform.converters import io.sentry.kotlin.multiplatform.JvmSpanStatus import io.sentry.kotlin.multiplatform.SpanStatus diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SamplingContext.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SamplingContext.kt index 55da0255..f4eb46e0 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SamplingContext.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SamplingContext.kt @@ -1,5 +1,7 @@ package io.sentry.kotlin.multiplatform +public typealias CustomSamplingContext = Map? + /** * Context used by [io.sentry.kotlin.multiplatform.SentryOptions.tracesSampler] to determine if transaction * is going to be sampled. @@ -9,5 +11,5 @@ public data class SamplingContext( public val transactionContext: TransactionContext, /** Arbitrary data used to determine if transaction is going to be sampled. */ - public val customSamplingContext: Map? + public val customSamplingContext: CustomSamplingContext ) diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt index 414dd15c..b23a3065 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt @@ -33,12 +33,12 @@ internal expect object SentryBridge { fun startTransaction( transactionContext: TransactionContext, - customSamplingContext: Map? + customSamplingContext: CustomSamplingContext ): Span fun startTransaction( transactionContext: TransactionContext, - customSamplingContext: Map?, + customSamplingContext: CustomSamplingContext, bindToScope: Boolean ): Span diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryKMP.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryKMP.kt index 96a30fda..ef117430 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryKMP.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryKMP.kt @@ -142,6 +142,38 @@ public object Sentry { return SentryBridge.startTransaction(name, operation, bindToScope) } + /** + * Starts a new transaction and returns a new `Span` representing it. The `Span` can be + * used to record additional information about the transaction or add child spans. + * + * @param transactionContext The transaction context. + * @param customSamplingContext The custom sampling context. + * @return A new `Span` representing the transaction. + */ + public fun startTransaction( + transactionContext: TransactionContext, + customSamplingContext: CustomSamplingContext + ): Span { + return SentryBridge.startTransaction(transactionContext, customSamplingContext) + } + + /** + * Starts a new transaction and returns a new `Span` representing it. The `Span` can be + * used to record additional information about the transaction or add child spans. + * + * @param transactionContext The transaction context. + * @param customSamplingContext The custom sampling context. + * @param bindToScope Whether to bind the transaction to the current scope. + * @return A new `Span` representing the transaction. + */ + public fun startTransaction( + transactionContext: TransactionContext, + customSamplingContext: CustomSamplingContext, + bindToScope: Boolean + ): Span { + return SentryBridge.startTransaction(transactionContext, customSamplingContext, bindToScope) + } + /** * Apple: returns the active root transaction * diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SpanContext.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SpanContext.kt index 75aaf9a7..e21e2dce 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SpanContext.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SpanContext.kt @@ -3,6 +3,8 @@ package io.sentry.kotlin.multiplatform import io.sentry.kotlin.multiplatform.protocol.SentryId import io.sentry.kotlin.multiplatform.protocol.SpanId +public typealias SamplingDecision = Boolean? + /** An interface representing the context of a span. */ public interface SpanContext { /** The name of the operation associated with the span.*/ @@ -22,5 +24,5 @@ public interface SpanContext { public val description: String? /** Indicates if the span is sampled.*/ - public val sampled: Boolean? + public val sampled: SamplingDecision } diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContext.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContext.kt index 25c405f3..7c36a70b 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContext.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/TransactionContext.kt @@ -13,32 +13,33 @@ public interface TransactionContext : SpanContext { public val transactionNameSource: TransactionNameSource /** Indicates if the parent transaction is sampled. */ - public val parentSampled: Boolean + public val parentSampled: Boolean? } /** The default Transaction Context implementation. */ -public class TransactionContextImpl(override val operation: String) : TransactionContext { +internal class TransactionContextImpl(override val operation: String) : TransactionContext { override var name: String = "" override var sampled: Boolean? = null - override var parentSampled: Boolean = false + override var parentSampled: Boolean? = null override var traceId: SentryId = SentryId.EMPTY_ID override var spanId: SpanId = SpanId.EMPTY_ID override var parentSpanId: SpanId? = null override var description: String? = null override var transactionNameSource: TransactionNameSource = TransactionNameSource.CUSTOM - public constructor(operation: String, name: String) : this(operation) { + constructor(operation: String, name: String) : this(operation) { this.name = name } - public constructor(operation: String, name: String, sampled: Boolean?) : this(operation, name) { - this.name = name + constructor(operation: String, name: String, sampled: Boolean?) : this(operation, name) { this.sampled = sampled } } public fun TransactionContext(operation: String): TransactionContext = TransactionContextImpl(operation) -public fun TransactionContext(operation: String, name: String): TransactionContext = - TransactionContextImpl(operation, name) -public fun TransactionContext(operation: String, name: String, sampled: Boolean): TransactionContext = - TransactionContextImpl(operation, name, sampled) + +public fun TransactionContext(name: String, operation: String): TransactionContext = + TransactionContextImpl(name = name, operation = operation) + +public fun TransactionContext(name: String, operation: String, sampled: Boolean): TransactionContext = + TransactionContextImpl(name = name, operation = operation, sampled = sampled) diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryTransactionTest.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryTransactionTest.kt new file mode 100644 index 00000000..13a2e7c3 --- /dev/null +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryTransactionTest.kt @@ -0,0 +1,349 @@ +package io.sentry.kotlin.multiplatform + +import io.sentry.kotlin.multiplatform.fakes.createFakeTransactionContext +import io.sentry.kotlin.multiplatform.utils.fakeDsn +import kotlin.test.BeforeTest +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertNull + +class SentryTransactionTest : BaseSentryTest() { + class Fixture { + val name = "test name" + val operation = "test description" + + internal fun getSut( + name: String = this@Fixture.name, + operation: String = this@Fixture.operation, + bindToScope: Boolean + ): Span { + return Sentry.startTransaction(name, operation, bindToScope) + } + + internal fun getSut( + name: String = this@Fixture.name, + operation: String = this@Fixture.operation + ): Span { + return Sentry.startTransaction(name, operation) + } + + internal fun getSutWithTransactionContext( + transactionContext: TransactionContext, + customSamplingContext: CustomSamplingContext + ): Span { + return Sentry.startTransaction(transactionContext, customSamplingContext) + } + } + + private lateinit var fixture: Fixture + + @BeforeTest + fun setup() { + fixture = Fixture() + } + + @Test + fun `GIVEN Sentry init AND tracesSampler set WHEN transaction finishes THEN receive correct name`() { + // GIVEN + var actualName = "" + Sentry.init { + it.dsn = fakeDsn + it.tracesSampler = { context -> + print("hello") + actualName = context.transactionContext.name + null + } + } + + // WHEN + val transaction = fixture.getSut(fixture.name, fixture.operation) + transaction.finish() + + // THEN + assertEquals(fixture.name, actualName) + } + + @Test + fun `GIVEN Sentry init AND tracesSampler set WHEN transaction started and finishes THEN receive correct spanId`() { + // GIVEN + var actualSpanId = "" + Sentry.init { + it.dsn = fakeDsn + it.tracesSampler = { context -> + actualSpanId = context.transactionContext.spanId.toString() + null + } + } + + // WHEN + val transaction = fixture.getSut() + transaction.finish() + + // THEN + assertEquals(transaction.spanId.toString(), actualSpanId) + } + + @Test + fun `GIVEN Sentry init AND parent + child spans WHEN both started and finished THEN child parentSpanId equals spanId of parent`() { + // GIVEN + Sentry.init { + it.dsn = fakeDsn + } + + // WHEN + val transaction = fixture.getSut() + val child = transaction.startChild("child") + child.finish() + transaction.finish() + + // THEN + assertEquals(child.parentSpanId?.toString(), transaction.spanId.toString()) + } + + @Test + fun `GIVEN Sentry init AND parent + child spans with operation WHEN both started and finished THEN child parentSpanId equals spanId of parent`() { + // GIVEN + Sentry.init { + it.dsn = fakeDsn + } + + // WHEN + val transaction = fixture.getSut() + val child = transaction.startChild("child", "description") + child.finish() + transaction.finish() + + // THEN + assertEquals(child.parentSpanId?.toString(), transaction.spanId.toString()) + } + + @Test + fun `GIVEN Sentry init WHEN transaction with bindToScope enabled started AND getSpan called THEN should return the correct transaction`() { + // GIVEN + Sentry.init { + it.dsn = fakeDsn + } + + // WHEN + val transaction = + fixture.getSut(bindToScope = true) + val activeTransactionSpanId = Sentry.getSpan()?.spanId + + // THEN + assertEquals( + activeTransactionSpanId, + transaction.spanId, + "activeTransactionSpanId should be equal to transaction.spanId" + ) + transaction.finish() + } + + @Test + fun `GIVEN Sentry init WHEN transaction with bindToScope disabled started AND getSpan called THEN getSpan should be null`() { + // GIVEN + Sentry.init { + it.dsn = fakeDsn + } + + // WHEN + val transaction = fixture.getSut() + val activeTransactionSpanId = Sentry.getSpan()?.spanId + + // THEN + assertNull(activeTransactionSpanId) + transaction.finish() + } + + @Test + fun `GIVEN Sentry init WHEN transaction with bindToScope enabled starts and finishes THEN calling getSpan after should be null`() { + // GIVEN + Sentry.init { + it.dsn = fakeDsn + } + + // WHEN + val transaction = fixture.getSut(bindToScope = true) + transaction.finish() + + // THEN + assertNull(Sentry.getSpan()?.spanId) + } + + @Test + fun `GIVEN Sentry init WHEN transaction finishes with status OK THEN span status should be OK`() { + // GIVEN + Sentry.init { + it.dsn = fakeDsn + } + + // WHEN + val transaction = fixture.getSut() + transaction.finish(SpanStatus.OK) + + // THEN + assertEquals(SpanStatus.OK, transaction.status) + } + + @Test + fun `GIVEN Sentry init WHEN overriding status on transaction THEN status returns correct value`() { + // GIVEN + Sentry.init { + it.dsn = fakeDsn + } + + // WHEN + val transaction = fixture.getSut() + transaction.status = SpanStatus.ABORTED + + // THEN + assertEquals(SpanStatus.ABORTED, transaction.status) + } + + @Test + fun `GIVEN Sentry init WHEN overriding operation on transaction THEN operation returns correct value`() { + // GIVEN + Sentry.init { + it.dsn = fakeDsn + } + val expectedOperation = "custom operation" + + // WHEN + val transaction = fixture.getSut() + transaction.operation = expectedOperation + + // THEN + assertEquals(expectedOperation, transaction.operation) + } + + @Test + fun `GIVEN Sentry init WHEN setData is used on transaction THEN getData will return correct value`() { + // GIVEN + Sentry.init { + it.dsn = fakeDsn + } + val expectedKey = "key" + val expectedValue = "value" + + // WHEN + val transaction = fixture.getSut() + transaction.setData(expectedKey, expectedValue) + + // THEN + assertEquals(expectedValue, transaction.getData(expectedKey)) + } + + @Test + fun `GIVEN Sentry init WHEN setTag is used on transaction THEN getTag will return correct value`() { + // GIVEN + Sentry.init { + it.dsn = fakeDsn + } + val expectedKey = "key" + val expectedValue = "value" + + // WHEN + val transaction = fixture.getSut() + transaction.setTag(expectedKey, expectedValue) + + // THEN + assertEquals(expectedValue, transaction.getTag(expectedKey)) + } + + @Test + fun `GIVEN Sentry init WHEN transaction starts with operation THEN span should return correct operation`() { + // GIVEN + Sentry.init { + it.dsn = fakeDsn + } + val expectedOperation = "custom operation" + + // WHEN + val transaction = fixture.getSut(operation = expectedOperation) + + // THEN + assertEquals(expectedOperation, transaction.operation) + } + + @Test + fun `GIVEN Sentry init WHEN transaction is given description THEN span should return correct description`() { + // GIVEN + Sentry.init { + it.dsn = fakeDsn + } + val expectedDescription = "custom description" + + // WHEN + val transaction = fixture.getSut() + transaction.description = expectedDescription + + // THEN + assertEquals(expectedDescription, transaction.description) + } + + @Test + fun `GIVEN Sentry init WHEN transaction calls finish THEN span should return isFinish true`() { + // GIVEN + Sentry.init { + it.dsn = fakeDsn + } + + // WHEN + val transaction = fixture.getSut() + transaction.finish() + + // THEN + assertEquals(true, transaction.isFinished) + } + + @Test + fun `GIVEN Sentry init WHEN startTransaction is given transactionContext with sampled not null THEN tracesSampler is ignored`() { + // GIVEN + var expectedTransactionContext: TransactionContext? = null + Sentry.init { + it.dsn = fakeDsn + it.tracesSampler = { _ -> + expectedTransactionContext = createFakeTransactionContext(operation = "different") + null + } + } + + // WHEN + fixture.getSutWithTransactionContext( + transactionContext = createFakeTransactionContext(sampled = true), + customSamplingContext = null + ) + + // THEN + assertNull(expectedTransactionContext) + } + + @Test + fun `GIVEN Sentry init WHEN startTransaction is given transactionContext with sampled null THEN tracesSampler is called`() { + // GIVEN + var actualTransactionContext: TransactionContext? = null + Sentry.init { + it.dsn = fakeDsn + it.tracesSampler = { context -> + actualTransactionContext = context.transactionContext + null + } + } + + // WHEN + val expectedTransactionContext = createFakeTransactionContext(sampled = null) + fixture.getSutWithTransactionContext( + transactionContext = expectedTransactionContext, + customSamplingContext = null + ) + + // THEN + assertEquals(expectedTransactionContext.name, actualTransactionContext?.name) + assertEquals(expectedTransactionContext.description, actualTransactionContext?.description) + assertEquals(expectedTransactionContext.sampled, actualTransactionContext?.sampled) + assertEquals(expectedTransactionContext.name, actualTransactionContext?.name) + assertEquals( + expectedTransactionContext.parentSampled, + actualTransactionContext?.parentSampled + ) + } +} diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SpanTest.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SpanTest.kt deleted file mode 100644 index 839fb34b..00000000 --- a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SpanTest.kt +++ /dev/null @@ -1,134 +0,0 @@ -package io.sentry.kotlin.multiplatform - -import io.sentry.kotlin.multiplatform.utils.fakeDsn -import kotlin.test.BeforeTest -import kotlin.test.Test -import kotlin.test.assertEquals -import kotlin.test.assertNull - -class SpanTest : BaseSentryTest() { - class Fixture { - private val operation = "test" - private val description = "test description" - - internal fun getSut(bindToScope: Boolean = false): Span { - return Sentry.startTransaction(operation, description, bindToScope) - } - } - - private lateinit var fixture: Fixture - - @BeforeTest - fun setup() { - fixture = Fixture() - } - - @Test - fun `GIVEN Sentry init AND tracesSampler set WHEN transaction finishes THEN receive correct name`() { - // GIVEN - val expectedName = "test" - var actualName = "" - Sentry.init { - it.dsn = fakeDsn - it.tracesSampler = { context -> - actualName = context.transactionContext.name - null - } - } - - // WHEN - val transaction = fixture.getSut() - transaction.finish() - - // THEN - assertEquals(expectedName, actualName) - } - - @Test - fun `GIVEN Sentry init AND tracesSampler set WHEN transaction started and finishes THEN receive correct spanId`() { - // GIVEN - var actualSpanId = "" - Sentry.init { - it.dsn = fakeDsn - it.tracesSampler = { context -> - actualSpanId = context.transactionContext.spanId.toString() - null - } - } - - // WHEN - val transaction = fixture.getSut() - transaction.finish() - - // THEN - assertEquals(transaction.spanId.toString(), actualSpanId) - } - - @Test - fun `GIVEN Sentry init AND parent + child spans WHEN both started and finished THEN child parentSpanId equals spanId of parent`() { - // GIVEN - Sentry.init { - it.dsn = fakeDsn - } - - // WHEN - val transaction = fixture.getSut() - val child = transaction.startChild("child") - child.finish() - transaction.finish() - - // THEN - assertEquals(child.parentSpanId?.toString(), transaction.spanId.toString()) - } - - @Test - fun `GIVEN Sentry init WHEN transaction with bindToScope enabled started AND getSpan called THEN should return the correct transaction`() { - // GIVEN - Sentry.init { - it.dsn = fakeDsn - } - - // WHEN - val transaction = fixture.getSut(bindToScope = true) - val activeTransactionSpanId = Sentry.getSpan()?.spanId - - // THEN - assertEquals( - activeTransactionSpanId, - transaction.spanId, - "activeTransactionSpanId should be equal to transaction.spanId" - ) - transaction.finish() - } - - @Test - fun `GIVEN Sentry init WHEN transaction with bindToScope disabled started AND getSpan called THEN getSpan should be null`() { - // GIVEN - Sentry.init { - it.dsn = fakeDsn - } - - // WHEN - val transaction = fixture.getSut() - val activeTransactionSpanId = Sentry.getSpan()?.spanId - - // THEN - assertNull(activeTransactionSpanId) - transaction.finish() - } - - @Test - fun `GIVEN Sentry init WHEN transaction with bindToScope enabled starts and finishes THEN calling getSpan after should be null`() { - // GIVEN - Sentry.init { - it.dsn = fakeDsn - } - - // WHEN - val transaction = fixture.getSut(bindToScope = true) - transaction.finish() - - // THEN - assertNull(Sentry.getSpan()?.spanId) - } -} diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TracesSamplerRateTest.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TracesSamplerTest.kt similarity index 82% rename from sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TracesSamplerRateTest.kt rename to sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TracesSamplerTest.kt index 74863eed..f592c020 100644 --- a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TracesSamplerRateTest.kt +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TracesSamplerTest.kt @@ -1,5 +1,6 @@ package io.sentry.kotlin.multiplatform +import io.sentry.kotlin.multiplatform.fakes.createFakeCustomSamplingContext import io.sentry.kotlin.multiplatform.fakes.createFakeTransactionContext import io.sentry.kotlin.multiplatform.protocol.SentryId import io.sentry.kotlin.multiplatform.protocol.SpanId @@ -7,24 +8,30 @@ import io.sentry.kotlin.multiplatform.utils.fakeSentryIdString import kotlin.test.BeforeTest import kotlin.test.Test import kotlin.test.assertEquals +import kotlin.test.assertNull -class TracesSamplerRateTest { +class TracesSamplerTest { class Fixture { val options = SentryOptions() - private fun getSamplingContext(transactionContext: TransactionContext): SamplingContext { - return SamplingContext(transactionContext) + private fun getSamplingContext( + transactionContext: TransactionContext, + customSamplingContext: CustomSamplingContext + ): SamplingContext { + return SamplingContext(transactionContext, customSamplingContext) } internal fun getSut( transactionContext: TransactionContext = createFakeTransactionContext(), + customSamplingContext: CustomSamplingContext = createFakeCustomSamplingContext(), sampler: (SamplingContext) -> Double? ): SamplingContext { this.options.tracesSampler = sampler - return getSamplingContext(transactionContext) + return getSamplingContext(transactionContext, customSamplingContext) } } + /** Returns the sample rate or null if not sampled. */ private fun SamplingContext.getSampleRate(): Double? { return fixture.options.tracesSampler?.invoke(this) } @@ -79,6 +86,18 @@ class TracesSamplerRateTest { assertEquals(sampleRate2, sut.getSampleRate()) } + @Test + fun `GIVEN null sampleRate WHEN traceSampler callback set to sampleRate THEN return null`() { + // GIVEN + val sampleRate = null + + // WHEN + val sut = fixture.getSut { sampleRate } + + // THEN + assertNull(sut.getSampleRate()) + } + @Test fun `GIVEN transactionContext name WHEN tracerSampler set AND sampled THEN returns correct TransactionContext name`() { // GIVEN @@ -222,4 +241,21 @@ class TracesSamplerRateTest { // THEN assertEquals(expectedTraceId, actualTraceId) } + + @Test + fun `GIVEN customSamplingContext WHEN tracerSampler set AND sampled THEN returns correct customSamplingContext`() { + // GIVEN + val expectedCustomSamplingContext = mapOf("user_id" to 12345) + + // WHEN + var actualCustomSamplingContext: CustomSamplingContext = null + val sut = fixture.getSut(customSamplingContext = expectedCustomSamplingContext) { + actualCustomSamplingContext = it.customSamplingContext + null + } + sut.getSampleRate() + + // THEN + assertEquals(expectedCustomSamplingContext, actualCustomSamplingContext) + } } diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TransactionContextTest.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TransactionContextTest.kt new file mode 100644 index 00000000..76bf12ba --- /dev/null +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/TransactionContextTest.kt @@ -0,0 +1,186 @@ +package io.sentry.kotlin.multiplatform + +import io.sentry.kotlin.multiplatform.protocol.SentryId +import io.sentry.kotlin.multiplatform.protocol.SpanId +import io.sentry.kotlin.multiplatform.protocol.TransactionNameSource +import kotlin.test.BeforeTest +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertNull +import kotlin.test.assertTrue + +class TransactionContextTest { + class Fixture { + val name = "test name" + val operation = "test operation" + val sampled = false + + fun getSut( + name: String = this.name, + operation: String = this.operation, + sampled: Boolean + ): TransactionContext { + return TransactionContext(operation = operation, name = name, sampled = sampled) + } + + fun getSut( + operation: String + ): TransactionContext { + return TransactionContext(operation = operation) + } + + fun getSut( + name: String = this.name, + operation: String = this.operation + ): TransactionContext { + return TransactionContext(operation = operation, name = name) + } + } + + private lateinit var fixture: Fixture + + @BeforeTest + fun setup() { + fixture = Fixture() + } + + @Test + fun `GIVEN name WHEN transactionContext created THEN receive correct name`() { + // GIVEN + val expectedName = "other name" + + // WHEN + val transactionContext = fixture.getSut(name = expectedName) + val actualName = transactionContext.name + + // THEN + assertEquals(expectedName, actualName) + } + + @Test + fun `GIVEN operation WHEN transactionContext created THEN receive correct operation`() { + // GIVEN + val expectedOperation = "other operation" + + // WHEN + val transactionContext = fixture.getSut( + operation = expectedOperation + ) + val actualOperation = transactionContext.operation + + // THEN + assertEquals(expectedOperation, actualOperation) + } + + @Test + fun `GIVEN sampled WHEN transactionContext created THEN receive correct sampled`() { + // GIVEN + val expectedSampled = true + + // WHEN + val transactionContext = fixture.getSut( + sampled = expectedSampled + ) + val actualSampled = transactionContext.sampled + + // THEN + assertEquals(expectedSampled, actualSampled) + } + + @Test + fun `WHEN transactionContext created THEN receive default parentSampled`() { + // WHEN + val transactionContext = fixture.getSut() + val actualParentSampled = transactionContext.parentSampled + + // THEN + assertNull(actualParentSampled) + } + + @Test + fun `WHEN transactionContext created THEN receive default traceId`() { + // WHEN + val transactionContext = fixture.getSut() + val actualTraceId = transactionContext.traceId + + // THEN + assertEquals(SentryId.EMPTY_ID, actualTraceId) + } + + @Test + fun `WHEN transactionContext created THEN receive default spanId`() { + // WHEN + val transactionContext = fixture.getSut() + val actualSpanId = transactionContext.spanId + + // THEN + assertEquals(SpanId.EMPTY_ID, actualSpanId) + } + + @Test + fun `WHEN transactionContext created THEN receive default parentSpanId`() { + // WHEN + val transactionContext = fixture.getSut() + val actualParentSpanId = transactionContext.parentSpanId + + // THEN + assertEquals(null, actualParentSpanId) + } + + @Test + fun `WHEN transactionContext created THEN receive default description`() { + // WHEN + val transactionContext = fixture.getSut() + val actualDescription = transactionContext.description + + // THEN + assertEquals(null, actualDescription) + } + + @Test + fun `WHEN transactionContext created THEN receive default transactionNameSource`() { + // WHEN + val transactionContext = fixture.getSut() + val actualTransactionNameSource = transactionContext.transactionNameSource + + // THEN + assertEquals(TransactionNameSource.CUSTOM, actualTransactionNameSource) + } + + @Test + fun `WHEN transactionContext with name and operation THEN sampling decision and parent sampling is not set`() { + // WHEN + val transactionContext = fixture.getSut() + + // THEN + assertNull(transactionContext.sampled) + assertNull(transactionContext.parentSampled) + } + + @Test + fun `GIVEN operation WHEN transactionContext created only with operation THEN receive correct operation`() { + // GIVEN + val expectedOperation = "other operation" + + // WHEN + val transactionContext = fixture.getSut( + operation = expectedOperation + ) + val actualOperation = transactionContext.operation + + // THEN + assertEquals(expectedOperation, actualOperation) + } + + @Test + fun `GIVEN TransactionContext instance WHEN checking the type THEN should be TransactionContextImpl`() { + // GIVEN + val transactionContext = fixture.getSut() + + // WHEN + val actual = transactionContext is TransactionContextImpl + + // THEN + assertTrue(actual) + } +} diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/fakes/FakeTransactionContext.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/fakes/FakeSamplingContext.kt similarity index 79% rename from sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/fakes/FakeTransactionContext.kt rename to sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/fakes/FakeSamplingContext.kt index bdbb1707..274aa9af 100644 --- a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/fakes/FakeTransactionContext.kt +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/fakes/FakeSamplingContext.kt @@ -1,5 +1,6 @@ package io.sentry.kotlin.multiplatform.fakes +import io.sentry.kotlin.multiplatform.CustomSamplingContext import io.sentry.kotlin.multiplatform.TransactionContext import io.sentry.kotlin.multiplatform.protocol.SentryId import io.sentry.kotlin.multiplatform.protocol.SpanId @@ -11,10 +12,10 @@ class FakeTransactionContext( override val spanId: SpanId, override val parentSpanId: SpanId?, override val description: String?, - override val sampled: Boolean, + override val sampled: Boolean?, override val name: String, override val transactionNameSource: TransactionNameSource, - override val parentSampled: Boolean + override val parentSampled: Boolean? ) : TransactionContext fun createFakeTransactionContext( @@ -23,10 +24,10 @@ fun createFakeTransactionContext( spanId: SpanId = SpanId.EMPTY_ID, parentSpanId: SpanId? = SpanId("123"), description: String? = "test description", - sampled: Boolean = false, + sampled: Boolean? = null, name: String = "test", transactionNameSource: TransactionNameSource = TransactionNameSource.TASK, - parentSampled: Boolean = false + parentSampled: Boolean? = null ): TransactionContext { return FakeTransactionContext( operation = operation, @@ -40,3 +41,7 @@ fun createFakeTransactionContext( parentSampled = parentSampled ) } + +fun createFakeCustomSamplingContext(): CustomSamplingContext { + return mapOf("user_id" to 12345, "search_results" to "search results") +} From c58cfb0897d7dd32fcad80adc927a7675664559d Mon Sep 17 00:00:00 2001 From: GIancarlo Buenaflor Date: Fri, 24 Nov 2023 15:16:02 +0100 Subject: [PATCH 33/43] Update sample --- .../shared/src/commonMain/kotlin/sample.kmp.app/SentrySetup.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/sentry-samples/kmp-app-cocoapods/shared/src/commonMain/kotlin/sample.kmp.app/SentrySetup.kt b/sentry-samples/kmp-app-cocoapods/shared/src/commonMain/kotlin/sample.kmp.app/SentrySetup.kt index aa93c331..e41b9533 100644 --- a/sentry-samples/kmp-app-cocoapods/shared/src/commonMain/kotlin/sample.kmp.app/SentrySetup.kt +++ b/sentry-samples/kmp-app-cocoapods/shared/src/commonMain/kotlin/sample.kmp.app/SentrySetup.kt @@ -37,7 +37,6 @@ private fun optionsConfiguration(): OptionsConfiguration { it.attachViewHierarchy = true it.release = "kmp-release@0.0.1" it.debug = true - it.tracesSampleRate = 1.0 it.failedRequestStatusCodes = listOf(HttpStatusCodeRange(400, 599)) it.failedRequestTargets = listOf("httpbin.org") it.beforeBreadcrumb = { breadcrumb -> From 3bf1246abf68fbe10e1ad64a00ca41af56003877 Mon Sep 17 00:00:00 2001 From: GIancarlo Buenaflor Date: Fri, 24 Nov 2023 15:20:39 +0100 Subject: [PATCH 34/43] apiDump --- .../android/sentry-kotlin-multiplatform.api | 20 ++++++++++++++----- .../api/jvm/sentry-kotlin-multiplatform.api | 20 ++++++++++++++----- 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/sentry-kotlin-multiplatform/api/android/sentry-kotlin-multiplatform.api b/sentry-kotlin-multiplatform/api/android/sentry-kotlin-multiplatform.api index 977a8b2f..f38e0913 100644 --- a/sentry-kotlin-multiplatform/api/android/sentry-kotlin-multiplatform.api +++ b/sentry-kotlin-multiplatform/api/android/sentry-kotlin-multiplatform.api @@ -46,11 +46,13 @@ public final class io/sentry/kotlin/multiplatform/HttpStatusCodeRange$Companion } public final class io/sentry/kotlin/multiplatform/SamplingContext { - public fun (Lio/sentry/kotlin/multiplatform/TransactionContext;)V + public fun (Lio/sentry/kotlin/multiplatform/TransactionContext;Ljava/util/Map;)V public final fun component1 ()Lio/sentry/kotlin/multiplatform/TransactionContext; - public final fun copy (Lio/sentry/kotlin/multiplatform/TransactionContext;)Lio/sentry/kotlin/multiplatform/SamplingContext; - public static synthetic fun copy$default (Lio/sentry/kotlin/multiplatform/SamplingContext;Lio/sentry/kotlin/multiplatform/TransactionContext;ILjava/lang/Object;)Lio/sentry/kotlin/multiplatform/SamplingContext; + public final fun component2 ()Ljava/util/Map; + public final fun copy (Lio/sentry/kotlin/multiplatform/TransactionContext;Ljava/util/Map;)Lio/sentry/kotlin/multiplatform/SamplingContext; + public static synthetic fun copy$default (Lio/sentry/kotlin/multiplatform/SamplingContext;Lio/sentry/kotlin/multiplatform/TransactionContext;Ljava/util/Map;ILjava/lang/Object;)Lio/sentry/kotlin/multiplatform/SamplingContext; public fun equals (Ljava/lang/Object;)Z + public final fun getCustomSamplingContext ()Ljava/util/Map; public final fun getTransactionContext ()Lio/sentry/kotlin/multiplatform/TransactionContext; public fun hashCode ()I public fun toString ()Ljava/lang/String; @@ -97,6 +99,8 @@ public final class io/sentry/kotlin/multiplatform/Sentry { public final fun init (Landroid/content/Context;Lkotlin/jvm/functions/Function1;)V public final fun init (Lkotlin/jvm/functions/Function1;)V public final fun setUser (Lio/sentry/kotlin/multiplatform/protocol/User;)V + public final fun startTransaction (Lio/sentry/kotlin/multiplatform/TransactionContext;Ljava/util/Map;)Lio/sentry/kotlin/multiplatform/Span; + public final fun startTransaction (Lio/sentry/kotlin/multiplatform/TransactionContext;Ljava/util/Map;Z)Lio/sentry/kotlin/multiplatform/Span; public final fun startTransaction (Ljava/lang/String;Ljava/lang/String;)Lio/sentry/kotlin/multiplatform/Span; public final fun startTransaction (Ljava/lang/String;Ljava/lang/String;Z)Lio/sentry/kotlin/multiplatform/Span; } @@ -240,7 +244,7 @@ public abstract interface class io/sentry/kotlin/multiplatform/SpanContext { public abstract fun getDescription ()Ljava/lang/String; public abstract fun getOperation ()Ljava/lang/String; public abstract fun getParentSpanId ()Lio/sentry/kotlin/multiplatform/protocol/SpanId; - public abstract fun getSampled ()Z + public abstract fun getSampled ()Ljava/lang/Boolean; public abstract fun getSpanId ()Lio/sentry/kotlin/multiplatform/protocol/SpanId; public abstract fun getTraceId ()Lio/sentry/kotlin/multiplatform/protocol/SentryId; } @@ -276,10 +280,16 @@ public final class io/sentry/kotlin/multiplatform/SpanStatus$Companion { public abstract interface class io/sentry/kotlin/multiplatform/TransactionContext : io/sentry/kotlin/multiplatform/SpanContext { public abstract fun getName ()Ljava/lang/String; - public abstract fun getParentSampled ()Z + public abstract fun getParentSampled ()Ljava/lang/Boolean; public abstract fun getTransactionNameSource ()Lio/sentry/kotlin/multiplatform/protocol/TransactionNameSource; } +public final class io/sentry/kotlin/multiplatform/TransactionContextKt { + public static final fun TransactionContext (Ljava/lang/String;)Lio/sentry/kotlin/multiplatform/TransactionContext; + public static final fun TransactionContext (Ljava/lang/String;Ljava/lang/String;)Lio/sentry/kotlin/multiplatform/TransactionContext; + public static final fun TransactionContext (Ljava/lang/String;Ljava/lang/String;Z)Lio/sentry/kotlin/multiplatform/TransactionContext; +} + public final class io/sentry/kotlin/multiplatform/protocol/Breadcrumb { public static final field Companion Lio/sentry/kotlin/multiplatform/protocol/Breadcrumb$Companion; public fun ()V diff --git a/sentry-kotlin-multiplatform/api/jvm/sentry-kotlin-multiplatform.api b/sentry-kotlin-multiplatform/api/jvm/sentry-kotlin-multiplatform.api index 7dc46e84..6a8006bd 100644 --- a/sentry-kotlin-multiplatform/api/jvm/sentry-kotlin-multiplatform.api +++ b/sentry-kotlin-multiplatform/api/jvm/sentry-kotlin-multiplatform.api @@ -43,11 +43,13 @@ public final class io/sentry/kotlin/multiplatform/HttpStatusCodeRange$Companion } public final class io/sentry/kotlin/multiplatform/SamplingContext { - public fun (Lio/sentry/kotlin/multiplatform/TransactionContext;)V + public fun (Lio/sentry/kotlin/multiplatform/TransactionContext;Ljava/util/Map;)V public final fun component1 ()Lio/sentry/kotlin/multiplatform/TransactionContext; - public final fun copy (Lio/sentry/kotlin/multiplatform/TransactionContext;)Lio/sentry/kotlin/multiplatform/SamplingContext; - public static synthetic fun copy$default (Lio/sentry/kotlin/multiplatform/SamplingContext;Lio/sentry/kotlin/multiplatform/TransactionContext;ILjava/lang/Object;)Lio/sentry/kotlin/multiplatform/SamplingContext; + public final fun component2 ()Ljava/util/Map; + public final fun copy (Lio/sentry/kotlin/multiplatform/TransactionContext;Ljava/util/Map;)Lio/sentry/kotlin/multiplatform/SamplingContext; + public static synthetic fun copy$default (Lio/sentry/kotlin/multiplatform/SamplingContext;Lio/sentry/kotlin/multiplatform/TransactionContext;Ljava/util/Map;ILjava/lang/Object;)Lio/sentry/kotlin/multiplatform/SamplingContext; public fun equals (Ljava/lang/Object;)Z + public final fun getCustomSamplingContext ()Ljava/util/Map; public final fun getTransactionContext ()Lio/sentry/kotlin/multiplatform/TransactionContext; public fun hashCode ()I public fun toString ()Ljava/lang/String; @@ -94,6 +96,8 @@ public final class io/sentry/kotlin/multiplatform/Sentry { public final fun init (Lio/sentry/kotlin/multiplatform/Context;Lkotlin/jvm/functions/Function1;)V public final fun init (Lkotlin/jvm/functions/Function1;)V public final fun setUser (Lio/sentry/kotlin/multiplatform/protocol/User;)V + public final fun startTransaction (Lio/sentry/kotlin/multiplatform/TransactionContext;Ljava/util/Map;)Lio/sentry/kotlin/multiplatform/Span; + public final fun startTransaction (Lio/sentry/kotlin/multiplatform/TransactionContext;Ljava/util/Map;Z)Lio/sentry/kotlin/multiplatform/Span; public final fun startTransaction (Ljava/lang/String;Ljava/lang/String;)Lio/sentry/kotlin/multiplatform/Span; public final fun startTransaction (Ljava/lang/String;Ljava/lang/String;Z)Lio/sentry/kotlin/multiplatform/Span; } @@ -237,7 +241,7 @@ public abstract interface class io/sentry/kotlin/multiplatform/SpanContext { public abstract fun getDescription ()Ljava/lang/String; public abstract fun getOperation ()Ljava/lang/String; public abstract fun getParentSpanId ()Lio/sentry/kotlin/multiplatform/protocol/SpanId; - public abstract fun getSampled ()Z + public abstract fun getSampled ()Ljava/lang/Boolean; public abstract fun getSpanId ()Lio/sentry/kotlin/multiplatform/protocol/SpanId; public abstract fun getTraceId ()Lio/sentry/kotlin/multiplatform/protocol/SentryId; } @@ -273,10 +277,16 @@ public final class io/sentry/kotlin/multiplatform/SpanStatus$Companion { public abstract interface class io/sentry/kotlin/multiplatform/TransactionContext : io/sentry/kotlin/multiplatform/SpanContext { public abstract fun getName ()Ljava/lang/String; - public abstract fun getParentSampled ()Z + public abstract fun getParentSampled ()Ljava/lang/Boolean; public abstract fun getTransactionNameSource ()Lio/sentry/kotlin/multiplatform/protocol/TransactionNameSource; } +public final class io/sentry/kotlin/multiplatform/TransactionContextKt { + public static final fun TransactionContext (Ljava/lang/String;)Lio/sentry/kotlin/multiplatform/TransactionContext; + public static final fun TransactionContext (Ljava/lang/String;Ljava/lang/String;)Lio/sentry/kotlin/multiplatform/TransactionContext; + public static final fun TransactionContext (Ljava/lang/String;Ljava/lang/String;Z)Lio/sentry/kotlin/multiplatform/TransactionContext; +} + public final class io/sentry/kotlin/multiplatform/protocol/Breadcrumb { public static final field Companion Lio/sentry/kotlin/multiplatform/protocol/Breadcrumb$Companion; public fun ()V From a460bce418f2855b896c070d64a02c40e8805326 Mon Sep 17 00:00:00 2001 From: GIancarlo Buenaflor Date: Fri, 24 Nov 2023 15:21:21 +0100 Subject: [PATCH 35/43] Update comment --- .../converters/CustomSamplingContextConvertersTest.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/sentry-kotlin-multiplatform/src/commonAppleTest/kotlin/io/sentry/kotlin/multiplatform/converters/CustomSamplingContextConvertersTest.kt b/sentry-kotlin-multiplatform/src/commonAppleTest/kotlin/io/sentry/kotlin/multiplatform/converters/CustomSamplingContextConvertersTest.kt index a0a73708..54dacf4b 100644 --- a/sentry-kotlin-multiplatform/src/commonAppleTest/kotlin/io/sentry/kotlin/multiplatform/converters/CustomSamplingContextConvertersTest.kt +++ b/sentry-kotlin-multiplatform/src/commonAppleTest/kotlin/io/sentry/kotlin/multiplatform/converters/CustomSamplingContextConvertersTest.kt @@ -7,7 +7,6 @@ import kotlin.test.Test import kotlin.test.assertTrue class CustomSamplingContextConvertersTest { - // Test that toCocoa doesn't crash @Test fun `GIVEN customSamplingContext WHEN toCocoa called THEN value is CocoaCustomSamplingContext`() { // GIVEN From 4738932acf78a57ca6fc47934cdd897edbaef818 Mon Sep 17 00:00:00 2001 From: GIancarlo Buenaflor Date: Fri, 24 Nov 2023 16:36:48 +0100 Subject: [PATCH 36/43] Remove unnecessary test --- .../multiplatform/SentryTransactionTest.kt | 30 ------------------- 1 file changed, 30 deletions(-) diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryTransactionTest.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryTransactionTest.kt index 13a2e7c3..c6f542cf 100644 --- a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryTransactionTest.kt +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryTransactionTest.kt @@ -316,34 +316,4 @@ class SentryTransactionTest : BaseSentryTest() { // THEN assertNull(expectedTransactionContext) } - - @Test - fun `GIVEN Sentry init WHEN startTransaction is given transactionContext with sampled null THEN tracesSampler is called`() { - // GIVEN - var actualTransactionContext: TransactionContext? = null - Sentry.init { - it.dsn = fakeDsn - it.tracesSampler = { context -> - actualTransactionContext = context.transactionContext - null - } - } - - // WHEN - val expectedTransactionContext = createFakeTransactionContext(sampled = null) - fixture.getSutWithTransactionContext( - transactionContext = expectedTransactionContext, - customSamplingContext = null - ) - - // THEN - assertEquals(expectedTransactionContext.name, actualTransactionContext?.name) - assertEquals(expectedTransactionContext.description, actualTransactionContext?.description) - assertEquals(expectedTransactionContext.sampled, actualTransactionContext?.sampled) - assertEquals(expectedTransactionContext.name, actualTransactionContext?.name) - assertEquals( - expectedTransactionContext.parentSampled, - actualTransactionContext?.parentSampled - ) - } } From c3cf0ba0c7967e40d9cb5c651a61315a1ec94169 Mon Sep 17 00:00:00 2001 From: GIancarlo Buenaflor Date: Thu, 7 Dec 2023 17:18:29 +0100 Subject: [PATCH 37/43] Fix jvm api error --- .../kotlin/multiplatform/SentryBridge.jvm.kt | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.jvm.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.jvm.kt index 403530ce..7a84f9e0 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.jvm.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.jvm.kt @@ -2,6 +2,7 @@ package io.sentry.kotlin.multiplatform import io.sentry.CustomSamplingContext import io.sentry.Sentry +import io.sentry.TransactionOptions import io.sentry.kotlin.multiplatform.converters.toJvm import io.sentry.kotlin.multiplatform.extensions.toJvmBreadcrumb import io.sentry.kotlin.multiplatform.extensions.toJvmUser @@ -65,7 +66,10 @@ internal actual object SentryBridge { } actual fun startTransaction(name: String, operation: String, bindToScope: Boolean): Span { - val jvmTransaction = Sentry.startTransaction(name, operation, bindToScope) + val jvmTransaction = Sentry.startTransaction( + name, + operation, + TransactionOptions().apply { this.isBindToScope = bindToScope }) return SpanProvider(jvmTransaction) } @@ -76,7 +80,9 @@ internal actual object SentryBridge { val jvmCustomSamplingContext = customSamplingContext?.toJvm() ?: CustomSamplingContext() val jvmTransactionContext = transactionContext.toJvm() val jvmTransaction = - Sentry.startTransaction(jvmTransactionContext, jvmCustomSamplingContext) + Sentry.startTransaction(jvmTransactionContext, TransactionOptions().apply { + this.customSamplingContext = jvmCustomSamplingContext + }) return SpanProvider(jvmTransaction) } @@ -88,7 +94,12 @@ internal actual object SentryBridge { val jvmCustomSamplingContext = customSamplingContext?.toJvm() val jvmTransactionContext = transactionContext.toJvm() val jvmTransaction = - Sentry.startTransaction(jvmTransactionContext, jvmCustomSamplingContext, bindToScope) + Sentry.startTransaction( + jvmTransactionContext, + TransactionOptions().apply { + this.isBindToScope = bindToScope + this.customSamplingContext = jvmCustomSamplingContext + }) return SpanProvider(jvmTransaction) } From 417ce29c6a772676806071d32a4fc333f3a6154b Mon Sep 17 00:00:00 2001 From: Sentry Github Bot Date: Thu, 7 Dec 2023 16:19:33 +0000 Subject: [PATCH 38/43] Format code --- .../kotlin/multiplatform/SentryBridge.jvm.kt | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.jvm.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.jvm.kt index 7a84f9e0..5a0341ae 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.jvm.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.jvm.kt @@ -69,7 +69,8 @@ internal actual object SentryBridge { val jvmTransaction = Sentry.startTransaction( name, operation, - TransactionOptions().apply { this.isBindToScope = bindToScope }) + TransactionOptions().apply { this.isBindToScope = bindToScope } + ) return SpanProvider(jvmTransaction) } @@ -80,9 +81,12 @@ internal actual object SentryBridge { val jvmCustomSamplingContext = customSamplingContext?.toJvm() ?: CustomSamplingContext() val jvmTransactionContext = transactionContext.toJvm() val jvmTransaction = - Sentry.startTransaction(jvmTransactionContext, TransactionOptions().apply { - this.customSamplingContext = jvmCustomSamplingContext - }) + Sentry.startTransaction( + jvmTransactionContext, + TransactionOptions().apply { + this.customSamplingContext = jvmCustomSamplingContext + } + ) return SpanProvider(jvmTransaction) } @@ -99,7 +103,8 @@ internal actual object SentryBridge { TransactionOptions().apply { this.isBindToScope = bindToScope this.customSamplingContext = jvmCustomSamplingContext - }) + } + ) return SpanProvider(jvmTransaction) } From 590bb64f9ddef5ec0b2de6c5055a28bbe0941427 Mon Sep 17 00:00:00 2001 From: GIancarlo Buenaflor Date: Thu, 7 Dec 2023 17:22:45 +0100 Subject: [PATCH 39/43] trigger ci --- .../kotlin/io/sentry/kotlin/multiplatform/SentryBridge.jvm.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.jvm.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.jvm.kt index 5a0341ae..9ed64f80 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.jvm.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.jvm.kt @@ -27,6 +27,7 @@ internal actual object SentryBridge { actual fun captureMessage(message: String): SentryId { val jvmSentryId = Sentry.captureMessage(message) return SentryId(jvmSentryId.toString()) + } actual fun captureMessage(message: String, scopeCallback: ScopeCallback): SentryId { From 264dcdb581a6b2159b16c7fe15d8f34c07f51168 Mon Sep 17 00:00:00 2001 From: GIancarlo Buenaflor Date: Thu, 7 Dec 2023 17:22:53 +0100 Subject: [PATCH 40/43] Retrigger ci --- .../kotlin/io/sentry/kotlin/multiplatform/SentryBridge.jvm.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.jvm.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.jvm.kt index 9ed64f80..5a0341ae 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.jvm.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.jvm.kt @@ -27,7 +27,6 @@ internal actual object SentryBridge { actual fun captureMessage(message: String): SentryId { val jvmSentryId = Sentry.captureMessage(message) return SentryId(jvmSentryId.toString()) - } actual fun captureMessage(message: String, scopeCallback: ScopeCallback): SentryId { From 78d7ab1368f17080838f72fdca5d34b154440a6a Mon Sep 17 00:00:00 2001 From: GIancarlo Buenaflor Date: Mon, 11 Dec 2023 10:50:25 +0100 Subject: [PATCH 41/43] Update provider to adapter --- .../api/android/sentry-kotlin-multiplatform.api | 2 ++ .../api/jvm/sentry-kotlin-multiplatform.api | 2 ++ ...peProvider.apple.kt => ScopeAdapter.apple.kt} | 2 +- .../kotlin/multiplatform/SentryBridge.apple.kt | 16 ++++++++-------- ...panProvider.apple.kt => SpanAdapter.apple.kt} | 6 +++--- .../kotlin/multiplatform/BaseSentryScopeTest.kt | 2 +- ...{ScopeProvider.jvm.kt => ScopeAdapter.jvm.kt} | 2 +- .../kotlin/multiplatform/SentryBridge.jvm.kt | 12 ++++++------ .../{SpanProvider.jvm.kt => SpanAdapter.jvm.kt} | 6 +++--- .../kotlin/multiplatform/BaseSentryScopeTest.kt | 2 +- 10 files changed, 28 insertions(+), 24 deletions(-) rename sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/{ScopeProvider.apple.kt => ScopeAdapter.apple.kt} (98%) rename sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/{SpanProvider.apple.kt => SpanAdapter.apple.kt} (92%) rename sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/{ScopeProvider.jvm.kt => ScopeAdapter.jvm.kt} (97%) rename sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/{SpanProvider.jvm.kt => SpanAdapter.jvm.kt} (92%) diff --git a/sentry-kotlin-multiplatform/api/android/sentry-kotlin-multiplatform.api b/sentry-kotlin-multiplatform/api/android/sentry-kotlin-multiplatform.api index e8b4bfad..063c8c16 100644 --- a/sentry-kotlin-multiplatform/api/android/sentry-kotlin-multiplatform.api +++ b/sentry-kotlin-multiplatform/api/android/sentry-kotlin-multiplatform.api @@ -270,6 +270,7 @@ public final class io/sentry/kotlin/multiplatform/SpanStatus : java/lang/Enum { public static final field UNIMPLEMENTED Lio/sentry/kotlin/multiplatform/SpanStatus; public static final field UNKNOWN Lio/sentry/kotlin/multiplatform/SpanStatus; public static final field UNKNOWN_ERROR Lio/sentry/kotlin/multiplatform/SpanStatus; + public static fun getEntries ()Lkotlin/enums/EnumEntries; public static fun valueOf (Ljava/lang/String;)Lio/sentry/kotlin/multiplatform/SpanStatus; public static fun values ()[Lio/sentry/kotlin/multiplatform/SpanStatus; } @@ -440,6 +441,7 @@ public final class io/sentry/kotlin/multiplatform/protocol/TransactionNameSource public static final field TASK Lio/sentry/kotlin/multiplatform/protocol/TransactionNameSource; public static final field URL Lio/sentry/kotlin/multiplatform/protocol/TransactionNameSource; public static final field VIEW Lio/sentry/kotlin/multiplatform/protocol/TransactionNameSource; + public static fun getEntries ()Lkotlin/enums/EnumEntries; public static fun valueOf (Ljava/lang/String;)Lio/sentry/kotlin/multiplatform/protocol/TransactionNameSource; public static fun values ()[Lio/sentry/kotlin/multiplatform/protocol/TransactionNameSource; } diff --git a/sentry-kotlin-multiplatform/api/jvm/sentry-kotlin-multiplatform.api b/sentry-kotlin-multiplatform/api/jvm/sentry-kotlin-multiplatform.api index 680179cc..6aaeb105 100644 --- a/sentry-kotlin-multiplatform/api/jvm/sentry-kotlin-multiplatform.api +++ b/sentry-kotlin-multiplatform/api/jvm/sentry-kotlin-multiplatform.api @@ -267,6 +267,7 @@ public final class io/sentry/kotlin/multiplatform/SpanStatus : java/lang/Enum { public static final field UNIMPLEMENTED Lio/sentry/kotlin/multiplatform/SpanStatus; public static final field UNKNOWN Lio/sentry/kotlin/multiplatform/SpanStatus; public static final field UNKNOWN_ERROR Lio/sentry/kotlin/multiplatform/SpanStatus; + public static fun getEntries ()Lkotlin/enums/EnumEntries; public static fun valueOf (Ljava/lang/String;)Lio/sentry/kotlin/multiplatform/SpanStatus; public static fun values ()[Lio/sentry/kotlin/multiplatform/SpanStatus; } @@ -437,6 +438,7 @@ public final class io/sentry/kotlin/multiplatform/protocol/TransactionNameSource public static final field TASK Lio/sentry/kotlin/multiplatform/protocol/TransactionNameSource; public static final field URL Lio/sentry/kotlin/multiplatform/protocol/TransactionNameSource; public static final field VIEW Lio/sentry/kotlin/multiplatform/protocol/TransactionNameSource; + public static fun getEntries ()Lkotlin/enums/EnumEntries; public static fun valueOf (Ljava/lang/String;)Lio/sentry/kotlin/multiplatform/protocol/TransactionNameSource; public static fun values ()[Lio/sentry/kotlin/multiplatform/protocol/TransactionNameSource; } diff --git a/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/ScopeProvider.apple.kt b/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/ScopeAdapter.apple.kt similarity index 98% rename from sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/ScopeProvider.apple.kt rename to sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/ScopeAdapter.apple.kt index f071ad2f..f5762445 100644 --- a/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/ScopeProvider.apple.kt +++ b/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/ScopeAdapter.apple.kt @@ -10,7 +10,7 @@ import io.sentry.kotlin.multiplatform.protocol.Breadcrumb import io.sentry.kotlin.multiplatform.protocol.User import Scope.Sentry.SentryScope as PrivateCocoaScope -internal class ScopeProvider(private val scope: CocoaScope) : Scope { +internal class ScopeAdapter(private val scope: CocoaScope) : Scope { /* This bridge exposes private Cocoa SDK API to fetch internal properties such as user, level, etc. We need this in order to return properties because the Cocoa SDK doesn't implement getters. diff --git a/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.apple.kt b/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.apple.kt index 9ba4c562..f113ddcf 100644 --- a/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.apple.kt +++ b/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.apple.kt @@ -67,12 +67,12 @@ internal actual object SentryBridge { actual fun startTransaction(name: String, operation: String): Span { val cocoaSpan = SentrySDK.startTransactionWithName(name, operation) - return SpanProvider(cocoaSpan) + return SpanAdapter(cocoaSpan) } actual fun startTransaction(name: String, operation: String, bindToScope: Boolean): Span { val cocoaSpan = SentrySDK.startTransactionWithName(name, operation, bindToScope) - return SpanProvider(cocoaSpan) + return SpanAdapter(cocoaSpan) } actual fun startTransaction( @@ -83,7 +83,7 @@ internal actual object SentryBridge { transactionContext.toCocoa(), customSamplingContext?.toCocoa() ?: mapOf() ) - return SpanProvider(cocoaSpan) + return SpanAdapter(cocoaSpan) } actual fun startTransaction( @@ -96,12 +96,12 @@ internal actual object SentryBridge { bindToScope, customSamplingContext?.toCocoa() ?: mapOf() ) - return SpanProvider(cocoaSpan) + return SpanAdapter(cocoaSpan) } actual fun getSpan(): Span? { val cocoaSpan = SentrySDK.span - return cocoaSpan?.let { SpanProvider(it) } + return cocoaSpan?.let { SpanAdapter(it) } } actual fun close() { @@ -110,10 +110,10 @@ internal actual object SentryBridge { private fun configureScopeCallback(scopeCallback: ScopeCallback): (CocoaScope?) -> Unit { return { cocoaScope -> - val cocoaScopeProvider = cocoaScope?.let { - ScopeProvider(it) + val cocoaScopeAdapter = cocoaScope?.let { + ScopeAdapter(it) } - cocoaScopeProvider?.let { + cocoaScopeAdapter?.let { scopeCallback.invoke(it) } } diff --git a/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/SpanProvider.apple.kt b/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/SpanAdapter.apple.kt similarity index 92% rename from sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/SpanProvider.apple.kt rename to sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/SpanAdapter.apple.kt index e1e4fdeb..f7542fa7 100644 --- a/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/SpanProvider.apple.kt +++ b/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/SpanAdapter.apple.kt @@ -5,16 +5,16 @@ import io.sentry.kotlin.multiplatform.converters.toCocoa import io.sentry.kotlin.multiplatform.converters.toKmp import io.sentry.kotlin.multiplatform.protocol.SpanId -internal class SpanProvider(private val cocoaSpan: SentrySpanProtocol) : Span { +internal class SpanAdapter(private val cocoaSpan: SentrySpanProtocol) : Span { override fun startChild(operation: String): Span { val cocoaSpan = cocoaSpan.startChildWithOperation(operation) - return SpanProvider(cocoaSpan) + return SpanAdapter(cocoaSpan) } override fun startChild(operation: String, description: String?): Span { val cocoaSpan = cocoaSpan.startChildWithOperation(operation = operation, description = description) - return SpanProvider(cocoaSpan) + return SpanAdapter(cocoaSpan) } override fun finish() { diff --git a/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/BaseSentryScopeTest.kt b/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/BaseSentryScopeTest.kt index dc17644f..922d125b 100644 --- a/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/BaseSentryScopeTest.kt +++ b/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/BaseSentryScopeTest.kt @@ -5,6 +5,6 @@ import cocoapods.Sentry.SentryScope as CocoaScope actual abstract class BaseSentryScopeTest { actual fun initializeScope(): Scope { val cocoaScope = CocoaScope() - return ScopeProvider(cocoaScope) + return ScopeAdapter(cocoaScope) } } diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/ScopeProvider.jvm.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/ScopeAdapter.jvm.kt similarity index 97% rename from sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/ScopeProvider.jvm.kt rename to sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/ScopeAdapter.jvm.kt index ec348da7..28f79bf6 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/ScopeProvider.jvm.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/ScopeAdapter.jvm.kt @@ -8,7 +8,7 @@ import io.sentry.kotlin.multiplatform.extensions.toKmpUser import io.sentry.kotlin.multiplatform.protocol.Breadcrumb import io.sentry.kotlin.multiplatform.protocol.User -internal class ScopeProvider(private val scope: JvmIScope) : Scope { +internal class ScopeAdapter(private val scope: JvmIScope) : Scope { override var level: SentryLevel? set(value) { scope.level = value?.toJvmSentryLevel() diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.jvm.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.jvm.kt index 5a0341ae..8acab1ae 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.jvm.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.jvm.kt @@ -62,7 +62,7 @@ internal actual object SentryBridge { actual fun startTransaction(name: String, operation: String): Span { val jvmTransaction = Sentry.startTransaction(name, operation) - return SpanProvider(jvmTransaction) + return SpanAdapter(jvmTransaction) } actual fun startTransaction(name: String, operation: String, bindToScope: Boolean): Span { @@ -71,7 +71,7 @@ internal actual object SentryBridge { operation, TransactionOptions().apply { this.isBindToScope = bindToScope } ) - return SpanProvider(jvmTransaction) + return SpanAdapter(jvmTransaction) } actual fun startTransaction( @@ -87,7 +87,7 @@ internal actual object SentryBridge { this.customSamplingContext = jvmCustomSamplingContext } ) - return SpanProvider(jvmTransaction) + return SpanAdapter(jvmTransaction) } actual fun startTransaction( @@ -105,12 +105,12 @@ internal actual object SentryBridge { this.customSamplingContext = jvmCustomSamplingContext } ) - return SpanProvider(jvmTransaction) + return SpanAdapter(jvmTransaction) } actual fun getSpan(): Span? { val jvmSpan = Sentry.getSpan() - return jvmSpan?.let { SpanProvider(it) } + return jvmSpan?.let { SpanAdapter(it) } } actual fun close() { @@ -119,7 +119,7 @@ internal actual object SentryBridge { private fun configureScopeCallback(scopeCallback: ScopeCallback): (JvmIScope) -> Unit { return { - val jvmScopeProvider = ScopeProvider(it) + val jvmScopeProvider = ScopeAdapter(it) scopeCallback.invoke(jvmScopeProvider) } } diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SpanProvider.jvm.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SpanAdapter.jvm.kt similarity index 92% rename from sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SpanProvider.jvm.kt rename to sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SpanAdapter.jvm.kt index 87142150..d858b887 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SpanProvider.jvm.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SpanAdapter.jvm.kt @@ -5,15 +5,15 @@ import io.sentry.kotlin.multiplatform.converters.toJvm import io.sentry.kotlin.multiplatform.converters.toKmp import io.sentry.kotlin.multiplatform.protocol.SpanId -internal class SpanProvider(private val jvmSpan: ISpan) : Span { +internal class SpanAdapter(private val jvmSpan: ISpan) : Span { override fun startChild(operation: String): Span { val jvmSpan = jvmSpan.startChild(operation) - return SpanProvider(jvmSpan) + return SpanAdapter(jvmSpan) } override fun startChild(operation: String, description: String?): Span { val jvmSpan = jvmSpan.startChild(operation, description) - return SpanProvider(jvmSpan) + return SpanAdapter(jvmSpan) } override fun finish() { diff --git a/sentry-kotlin-multiplatform/src/commonJvmTest/kotlin/io/sentry/kotlin/multiplatform/BaseSentryScopeTest.kt b/sentry-kotlin-multiplatform/src/commonJvmTest/kotlin/io/sentry/kotlin/multiplatform/BaseSentryScopeTest.kt index c6ae0278..5a347f08 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmTest/kotlin/io/sentry/kotlin/multiplatform/BaseSentryScopeTest.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmTest/kotlin/io/sentry/kotlin/multiplatform/BaseSentryScopeTest.kt @@ -5,6 +5,6 @@ import io.sentry.SentryOptions actual abstract class BaseSentryScopeTest { actual fun initializeScope(): Scope { val jvmScope = JvmScope(SentryOptions()) - return ScopeProvider(jvmScope) + return ScopeAdapter(jvmScope) } } From b10efb09132e9ffb0524e1b9e6143635daeaaac7 Mon Sep 17 00:00:00 2001 From: GIancarlo Buenaflor Date: Mon, 11 Dec 2023 10:59:17 +0100 Subject: [PATCH 42/43] Revert deps bump --- .github/workflows/update-deps.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/update-deps.yml b/.github/workflows/update-deps.yml index b76a374c..d75f37e9 100644 --- a/.github/workflows/update-deps.yml +++ b/.github/workflows/update-deps.yml @@ -11,7 +11,7 @@ on: jobs: cocoa: - uses: getsentry/github-workflows/.github/workflows/updater.yml@v2 + uses: getsentry/github-workflows/.github/workflows/updater.yml@v1 with: path: scripts/update-cocoa.sh name: Cocoa SDK @@ -20,7 +20,7 @@ jobs: api_token: ${{ secrets.CI_DEPLOY_KEY }} java: - uses: getsentry/github-workflows/.github/workflows/updater.yml@v2 + uses: getsentry/github-workflows/.github/workflows/updater.yml@v1 with: path: scripts/update-java.sh name: Java SDK From 2b27001dd41d7755a5e2310986c5298e42563f29 Mon Sep 17 00:00:00 2001 From: GIancarlo Buenaflor Date: Mon, 11 Dec 2023 11:08:26 +0100 Subject: [PATCH 43/43] Fix analyze --- config/detekt/baseline.xml | 4 ++-- config/detekt/detekt.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/config/detekt/baseline.xml b/config/detekt/baseline.xml index 77b17b8f..2d798bfc 100644 --- a/config/detekt/baseline.xml +++ b/config/detekt/baseline.xml @@ -2,9 +2,9 @@ - SwallowedException:ScopeProvider.apple.kt$ScopeProvider$e: Throwable + SwallowedException:ScopeAdapter.apple.kt$ScopeAdapter$e: Throwable SwallowedException:SentryLevel.kt$SentryLevel.Companion$throwable: Throwable - TooGenericExceptionCaught:ScopeProvider.apple.kt$ScopeProvider$e: Throwable + TooGenericExceptionCaught:ScopeAdapter.apple.kt$ScopeAdapter$e: Throwable TooGenericExceptionCaught:SentryLevel.kt$SentryLevel.Companion$throwable: Throwable TooGenericExceptionThrown:SentryKMP.kt$Sentry$throw RuntimeException("Uncaught Exception from Kotlin Multiplatform.") diff --git a/config/detekt/detekt.yml b/config/detekt/detekt.yml index d0cebae4..45eb57f0 100644 --- a/config/detekt/detekt.yml +++ b/config/detekt/detekt.yml @@ -25,7 +25,7 @@ complexity: excludes: [ "**/SentryKMP.kt", "**/SentryBridge.*", - "**/ScopeProvider.*", + "**/ScopeAdapter.*", "**/Scope.kt", "**/Breadcrumb.kt", ]