-
-
Notifications
You must be signed in to change notification settings - Fork 19
Add ability to perform basic custom instrumentation with Transaction and Spans #83
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Please also provide data class SpanContext(val span: Span) : AbstractCoroutineContextElement(SpanContext) {
companion object Key : CoroutineContext.Key<SpanContext>
}
fun CoroutineContext.currentSpan(): Span {
return get(SpanContext)?.span ?: throw IllegalStateException("No active Span in context")
}
suspend fun <T> withTrace(
name: String,
spanName: String,
block: suspend CoroutineScope.() -> T
): T {
val trace = startTrace(name, spanName)
return withSpan(trace, block)
}
suspend fun <T> withSpan(name: String, block: suspend CoroutineScope.() -> T): T {
val span = currentCoroutineContext().currentSpan()
val childSpan = span.startChild(name)
return withSpan(childSpan, block)
}
suspend fun <T> withSpan(span: Span, block: suspend CoroutineScope.() -> T): T {
return try {
withContext(SpanContext(span), block)
} catch (e: Throwable) {
if (e is CancellationException) {
span.setStatus("cancelled")
} else {
span.setThrowable(e)
span.setStatus("error")
}
throw e
} finally {
span.finish()
}
} This allows to add the context to the coroutine context, which ensures it is propagates in suspend code with structured concurrency. This means the child span must no be propagated manually. The extension functions allow to instrument code as follows: suspend fun getData(): String {
return withSpan("getData") {
delay(1000)
"foo"
}
} |
For anyone looking into custom instrumentation here is a small/basic snippet you could use for now // in commonMain
interface SharedSentrySpan {
fun startChild(operation: String): SharedSentrySpan
fun finish()
}
expect fun startTransaction(name: String, operation: String): SharedSentrySpan // in androidMain
class SentrySpanAdapter(private val span: io.sentry.ISpan): SharedSentrySpan {
override fun startChild(operation: String): SharedSentrySpan {
return SentrySpanAdapter(span.startChild(operation))
}
override fun finish() {
span.finish()
}
}
actual fun startTransaction(name: String, operation: String): SharedSentrySpan {
return SentrySpanAdapter(io.sentry.Sentry.startTransaction(name, operation))
} // in iosMain
class SentrySpanAdapter(private val span: cocoapods.Sentry.SentrySpanProtocol): SharedSentrySpan {
override fun startChild(operation: String): SharedSentrySpan {
return SentrySpanAdapter(span.startChildWithOperation(operation))
}
override fun finish() {
span.finish()
}
}
actual fun startTransaction(name: String, operation: String): SharedSentrySpan {
return SentrySpanAdapter(cocoapods.Sentry.SentrySDK.startTransactionWithName(name, operation))
} |
This would allow developers to create custom transactions and spans in their code to capture information about their application's performance and behavior.
At the very least support:
Transaction
Span
startTransaction()
startChild()
getSpan()
tracesSampleRate
optiontracesSampler
optionAlign implementation with:
The text was updated successfully, but these errors were encountered: