Add transaction trees for opening a room so we can have a nice trace view

This commit is contained in:
Jorge Martín
2025-11-20 12:23:03 +01:00
committed by Jorge Martin Espinosa
parent 2a011bf072
commit 93feed38bf
13 changed files with 86 additions and 16 deletions

View File

@@ -16,4 +16,7 @@ sealed class AnalyticsLongRunningTransaction(
data object ResumeAppUntilNewRoomsReceived : AnalyticsLongRunningTransaction("App was resumed and new room list items arrived", null)
data object NotificationTapOpensTimeline : AnalyticsLongRunningTransaction("A notification was tapped and it opened a timeline", null)
data object OpenRoom : AnalyticsLongRunningTransaction("Open a room and see loaded items in the timeline", null)
data object LoadJoinedRoomFlow : AnalyticsLongRunningTransaction("Load joined room UI", "ui.load")
data object LoadMessagesUi : AnalyticsLongRunningTransaction("Load messages UI", "ui.load")
data object DisplayFirstTimelineItems : AnalyticsLongRunningTransaction("Get and display first timeline items", null)
}

View File

@@ -58,7 +58,10 @@ interface AnalyticsService : AnalyticsTracker, ErrorTracker {
/**
* Starts an [AnalyticsLongRunningTransaction], that can be shared with other components.
*/
fun startLongRunningTransaction(longRunningTransaction: AnalyticsLongRunningTransaction): AnalyticsTransaction
fun startLongRunningTransaction(
longRunningTransaction: AnalyticsLongRunningTransaction,
parentTransaction: AnalyticsTransaction? = null
): AnalyticsTransaction
/**
* Gets an ongoing [AnalyticsLongRunningTransaction], if it exists.
@@ -71,8 +74,14 @@ interface AnalyticsService : AnalyticsTracker, ErrorTracker {
fun removeLongRunningTransaction(longRunningTransaction: AnalyticsLongRunningTransaction): AnalyticsTransaction?
}
inline fun <T> AnalyticsService.recordTransaction(name: String, operation: String, block: (AnalyticsTransaction) -> T): T {
val transaction = startTransaction(name, operation)
inline fun <T> AnalyticsService.recordTransaction(
name: String,
operation: String,
parentTransaction: AnalyticsTransaction? = null,
block: (AnalyticsTransaction) -> T
): T {
val transaction = parentTransaction?.startChild(name, operation)
?: startTransaction(name, operation)
try {
val result = block(transaction)
return result

View File

@@ -153,8 +153,13 @@ class DefaultAnalyticsService(
} ?: NoopAnalyticsTransaction
}
override fun startLongRunningTransaction(longRunningTransaction: AnalyticsLongRunningTransaction): AnalyticsTransaction {
val transaction = startTransaction(longRunningTransaction.name, longRunningTransaction.operation)
override fun startLongRunningTransaction(
longRunningTransaction: AnalyticsLongRunningTransaction,
parentTransaction: AnalyticsTransaction?,
): AnalyticsTransaction {
val transaction = parentTransaction?.startChild(longRunningTransaction.name, longRunningTransaction.operation)
?: startTransaction(longRunningTransaction.name, longRunningTransaction.operation)
pendingLongRunningTransactions[longRunningTransaction] = transaction
return transaction
}

View File

@@ -39,7 +39,10 @@ class NoopAnalyticsService : AnalyticsService {
override fun trackError(throwable: Throwable) = Unit
override fun updateSuperProperties(updatedProperties: SuperProperties) = Unit
override fun startTransaction(name: String, operation: String?): AnalyticsTransaction = NoopAnalyticsTransaction
override fun startLongRunningTransaction(longRunningTransaction: AnalyticsLongRunningTransaction): AnalyticsTransaction = NoopAnalyticsTransaction
override fun startLongRunningTransaction(
longRunningTransaction: AnalyticsLongRunningTransaction,
parentTransaction: AnalyticsTransaction?,
): AnalyticsTransaction = NoopAnalyticsTransaction
override fun getLongRunningTransaction(longRunningTransaction: AnalyticsLongRunningTransaction): AnalyticsTransaction? = null
override fun removeLongRunningTransaction(longRunningTransaction: AnalyticsLongRunningTransaction) = NoopAnalyticsTransaction
}

View File

@@ -71,7 +71,10 @@ class FakeAnalyticsService(
}
override fun startTransaction(name: String, operation: String?): AnalyticsTransaction = NoopAnalyticsTransaction
override fun startLongRunningTransaction(longRunningTransaction: AnalyticsLongRunningTransaction): AnalyticsTransaction {
override fun startLongRunningTransaction(
longRunningTransaction: AnalyticsLongRunningTransaction,
parentTransaction: AnalyticsTransaction?
): AnalyticsTransaction {
longRunningTransactions[longRunningTransaction] = NoopAnalyticsTransaction
return NoopAnalyticsTransaction
}

View File

@@ -9,7 +9,9 @@ package io.element.android.services.analyticsproviders.sentry
import io.element.android.services.analyticsproviders.api.AnalyticsTransaction
import io.sentry.ISpan
import io.sentry.ITransaction
import io.sentry.Sentry
import timber.log.Timber
class SentryAnalyticsTransaction private constructor(span: ISpan) : AnalyticsTransaction {
constructor(name: String, operation: String?) : this(Sentry.startTransaction(name, operation.orEmpty()))
@@ -20,5 +22,9 @@ class SentryAnalyticsTransaction private constructor(span: ISpan) : AnalyticsTra
)
override fun setData(key: String, value: Any) = inner.setData(key, value)
override fun isFinished(): Boolean = inner.isFinished
override fun finish() = inner.finish()
override fun finish() {
val name = if (inner is ITransaction) inner.name else inner.operation
Timber.d("Finishing transaction: $name")
inner.finish()
}
}