Add transaction trees for opening a room so we can have a nice trace view
This commit is contained in:
parent
2a011bf072
commit
93feed38bf
13 changed files with 86 additions and 16 deletions
|
|
@ -12,6 +12,7 @@ import dev.zacsweers.metro.ContributesBinding
|
||||||
import dev.zacsweers.metro.SingleIn
|
import dev.zacsweers.metro.SingleIn
|
||||||
import io.element.android.libraries.di.annotations.AppCoroutineScope
|
import io.element.android.libraries.di.annotations.AppCoroutineScope
|
||||||
import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction
|
import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction
|
||||||
|
import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.ColdStartUntilCachedRoomList
|
||||||
import io.element.android.services.analytics.api.AnalyticsService
|
import io.element.android.services.analytics.api.AnalyticsService
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.flow.catch
|
import kotlinx.coroutines.flow.catch
|
||||||
|
|
@ -44,7 +45,7 @@ class DefaultAnalyticsColdStartWatcher(
|
||||||
if (hasConsent) {
|
if (hasConsent) {
|
||||||
if (isColdStart.get()) {
|
if (isColdStart.get()) {
|
||||||
Timber.d("Starting cold start check")
|
Timber.d("Starting cold start check")
|
||||||
analyticsService.startLongRunningTransaction(AnalyticsLongRunningTransaction.ColdStartUntilCachedRoomList)
|
analyticsService.startLongRunningTransaction(ColdStartUntilCachedRoomList)
|
||||||
} else {
|
} else {
|
||||||
error("The app is no longer in a cold start state")
|
error("The app is no longer in a cold start state")
|
||||||
}
|
}
|
||||||
|
|
@ -56,6 +57,7 @@ class DefaultAnalyticsColdStartWatcher(
|
||||||
|
|
||||||
override fun whenLoggingIn() {
|
override fun whenLoggingIn() {
|
||||||
if (isColdStart.getAndSet(false)) {
|
if (isColdStart.getAndSet(false)) {
|
||||||
|
analyticsService.removeLongRunningTransaction(ColdStartUntilCachedRoomList)
|
||||||
Timber.d("Canceled cold start check: user is logging in")
|
Timber.d("Canceled cold start check: user is logging in")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -63,7 +65,7 @@ class DefaultAnalyticsColdStartWatcher(
|
||||||
override fun onRoomListVisible() {
|
override fun onRoomListVisible() {
|
||||||
if (isColdStart.getAndSet(false)) {
|
if (isColdStart.getAndSet(false)) {
|
||||||
Timber.d("Room list is visible, finishing cold start check")
|
Timber.d("Room list is visible, finishing cold start check")
|
||||||
analyticsService.removeLongRunningTransaction(AnalyticsLongRunningTransaction.ColdStartUntilCachedRoomList)?.finish()
|
analyticsService.removeLongRunningTransaction(ColdStartUntilCachedRoomList)?.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,9 @@ import io.element.android.libraries.matrix.api.room.CurrentUserMembership
|
||||||
import io.element.android.libraries.matrix.api.room.RoomMembershipObserver
|
import io.element.android.libraries.matrix.api.room.RoomMembershipObserver
|
||||||
import io.element.android.libraries.matrix.api.room.alias.ResolvedRoomAlias
|
import io.element.android.libraries.matrix.api.room.alias.ResolvedRoomAlias
|
||||||
import io.element.android.libraries.matrix.ui.room.LoadingRoomState
|
import io.element.android.libraries.matrix.ui.room.LoadingRoomState
|
||||||
import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction
|
import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.LoadJoinedRoomFlow
|
||||||
|
import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.NotificationTapOpensTimeline
|
||||||
|
import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.OpenRoom
|
||||||
import io.element.android.services.analytics.api.AnalyticsService
|
import io.element.android.services.analytics.api.AnalyticsService
|
||||||
import kotlinx.coroutines.flow.SharingStarted
|
import kotlinx.coroutines.flow.SharingStarted
|
||||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||||
|
|
@ -111,7 +113,9 @@ class RoomFlowNode(
|
||||||
|
|
||||||
override fun onBuilt() {
|
override fun onBuilt() {
|
||||||
super.onBuilt()
|
super.onBuilt()
|
||||||
analyticsService.startLongRunningTransaction(AnalyticsLongRunningTransaction.OpenRoom)
|
val parentTransaction = analyticsService.getLongRunningTransaction(NotificationTapOpensTimeline)
|
||||||
|
val openRoomTransaction = analyticsService.startLongRunningTransaction(OpenRoom, parentTransaction)
|
||||||
|
analyticsService.startLongRunningTransaction(LoadJoinedRoomFlow, openRoomTransaction)
|
||||||
resolveRoomId()
|
resolveRoomId()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,10 @@ import io.element.android.libraries.matrix.api.core.ThreadId
|
||||||
import io.element.android.libraries.matrix.api.core.UserId
|
import io.element.android.libraries.matrix.api.core.UserId
|
||||||
import io.element.android.libraries.matrix.api.permalink.PermalinkData
|
import io.element.android.libraries.matrix.api.permalink.PermalinkData
|
||||||
import io.element.android.libraries.matrix.api.room.JoinedRoom
|
import io.element.android.libraries.matrix.api.room.JoinedRoom
|
||||||
|
import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.LoadJoinedRoomFlow
|
||||||
|
import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.LoadMessagesUi
|
||||||
|
import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.OpenRoom
|
||||||
|
import io.element.android.services.analytics.api.AnalyticsService
|
||||||
import io.element.android.services.appnavstate.api.ActiveRoomsHolder
|
import io.element.android.services.appnavstate.api.ActiveRoomsHolder
|
||||||
import io.element.android.services.appnavstate.api.AppNavigationStateService
|
import io.element.android.services.appnavstate.api.AppNavigationStateService
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
|
@ -66,6 +70,7 @@ class JoinedRoomLoadedFlowNode(
|
||||||
private val sessionCoroutineScope: CoroutineScope,
|
private val sessionCoroutineScope: CoroutineScope,
|
||||||
private val matrixClient: MatrixClient,
|
private val matrixClient: MatrixClient,
|
||||||
private val activeRoomsHolder: ActiveRoomsHolder,
|
private val activeRoomsHolder: ActiveRoomsHolder,
|
||||||
|
private val analyticsService: AnalyticsService,
|
||||||
roomGraphFactory: RoomGraphFactory,
|
roomGraphFactory: RoomGraphFactory,
|
||||||
) : BaseFlowNode<JoinedRoomLoadedFlowNode.NavTarget>(
|
) : BaseFlowNode<JoinedRoomLoadedFlowNode.NavTarget>(
|
||||||
backstack = BackStack(
|
backstack = BackStack(
|
||||||
|
|
@ -93,6 +98,8 @@ class JoinedRoomLoadedFlowNode(
|
||||||
init {
|
init {
|
||||||
lifecycle.subscribe(
|
lifecycle.subscribe(
|
||||||
onCreate = {
|
onCreate = {
|
||||||
|
val parent = analyticsService.getLongRunningTransaction(OpenRoom)
|
||||||
|
analyticsService.startLongRunningTransaction(LoadMessagesUi, parent)
|
||||||
Timber.v("OnCreate => ${inputs.room.roomId}")
|
Timber.v("OnCreate => ${inputs.room.roomId}")
|
||||||
appNavigationStateService.onNavigateToRoom(id, inputs.room.roomId)
|
appNavigationStateService.onNavigateToRoom(id, inputs.room.roomId)
|
||||||
activeRoomsHolder.addRoom(inputs.room)
|
activeRoomsHolder.addRoom(inputs.room)
|
||||||
|
|
@ -100,6 +107,7 @@ class JoinedRoomLoadedFlowNode(
|
||||||
trackVisitedRoom()
|
trackVisitedRoom()
|
||||||
},
|
},
|
||||||
onResume = {
|
onResume = {
|
||||||
|
analyticsService.removeLongRunningTransaction(LoadJoinedRoomFlow)?.finish()
|
||||||
sessionCoroutineScope.launch {
|
sessionCoroutineScope.launch {
|
||||||
inputs.room.subscribeToSync()
|
inputs.room.subscribeToSync()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ import io.element.android.libraries.matrix.test.FakeMatrixClient
|
||||||
import io.element.android.libraries.matrix.test.room.FakeBaseRoom
|
import io.element.android.libraries.matrix.test.room.FakeBaseRoom
|
||||||
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
|
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
|
||||||
import io.element.android.libraries.matrix.test.room.aRoomInfo
|
import io.element.android.libraries.matrix.test.room.aRoomInfo
|
||||||
|
import io.element.android.services.analytics.test.FakeAnalyticsService
|
||||||
import io.element.android.services.appnavstate.api.ActiveRoomsHolder
|
import io.element.android.services.appnavstate.api.ActiveRoomsHolder
|
||||||
import io.element.android.services.appnavstate.impl.DefaultActiveRoomsHolder
|
import io.element.android.services.appnavstate.impl.DefaultActiveRoomsHolder
|
||||||
import io.element.android.services.appnavstate.test.FakeAppNavigationStateService
|
import io.element.android.services.appnavstate.test.FakeAppNavigationStateService
|
||||||
|
|
@ -123,6 +124,7 @@ class JoinedRoomLoadedFlowNodeTest {
|
||||||
roomGraphFactory = FakeRoomGraphFactory(),
|
roomGraphFactory = FakeRoomGraphFactory(),
|
||||||
matrixClient = matrixClient,
|
matrixClient = matrixClient,
|
||||||
activeRoomsHolder = activeRoomsHolder,
|
activeRoomsHolder = activeRoomsHolder,
|
||||||
|
analyticsService = FakeAnalyticsService(),
|
||||||
)
|
)
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,7 @@ import io.element.android.libraries.matrix.api.timeline.Timeline
|
||||||
import io.element.android.libraries.matrix.api.timeline.item.TimelineItemDebugInfo
|
import io.element.android.libraries.matrix.api.timeline.item.TimelineItemDebugInfo
|
||||||
import io.element.android.libraries.mediaplayer.api.MediaPlayer
|
import io.element.android.libraries.mediaplayer.api.MediaPlayer
|
||||||
import io.element.android.libraries.ui.strings.CommonStrings
|
import io.element.android.libraries.ui.strings.CommonStrings
|
||||||
|
import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.LoadMessagesUi
|
||||||
import io.element.android.services.analytics.api.AnalyticsService
|
import io.element.android.services.analytics.api.AnalyticsService
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
import kotlinx.collections.immutable.toImmutableList
|
import kotlinx.collections.immutable.toImmutableList
|
||||||
|
|
@ -136,6 +137,9 @@ class MessagesNode(
|
||||||
onCreate = {
|
onCreate = {
|
||||||
sessionCoroutineScope.launch { analyticsService.capture(room.toAnalyticsViewRoom()) }
|
sessionCoroutineScope.launch { analyticsService.capture(room.toAnalyticsViewRoom()) }
|
||||||
},
|
},
|
||||||
|
onResume = {
|
||||||
|
analyticsService.removeLongRunningTransaction(LoadMessagesUi)?.finish()
|
||||||
|
},
|
||||||
onDestroy = {
|
onDestroy = {
|
||||||
mediaPlayer.close()
|
mediaPlayer.close()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,9 @@ import io.element.android.libraries.matrix.api.timeline.item.event.MessageShield
|
||||||
import io.element.android.libraries.matrix.api.timeline.item.event.TimelineItemEventOrigin
|
import io.element.android.libraries.matrix.api.timeline.item.event.TimelineItemEventOrigin
|
||||||
import io.element.android.libraries.matrix.ui.room.canSendMessageAsState
|
import io.element.android.libraries.matrix.ui.room.canSendMessageAsState
|
||||||
import io.element.android.libraries.preferences.api.store.SessionPreferencesStore
|
import io.element.android.libraries.preferences.api.store.SessionPreferencesStore
|
||||||
import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction
|
import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.DisplayFirstTimelineItems
|
||||||
|
import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.NotificationTapOpensTimeline
|
||||||
|
import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.OpenRoom
|
||||||
import io.element.android.services.analytics.api.AnalyticsService
|
import io.element.android.services.analytics.api.AnalyticsService
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
import kotlinx.collections.immutable.persistentListOf
|
import kotlinx.collections.immutable.persistentListOf
|
||||||
|
|
@ -111,6 +113,11 @@ class TimelinePresenter(
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun present(): TimelineState {
|
override fun present(): TimelineState {
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
val parent = analyticsService.getLongRunningTransaction(OpenRoom)
|
||||||
|
analyticsService.startLongRunningTransaction(DisplayFirstTimelineItems, parent)
|
||||||
|
}
|
||||||
|
|
||||||
val localScope = rememberCoroutineScope()
|
val localScope = rememberCoroutineScope()
|
||||||
|
|
||||||
val timelineMode = remember { timelineController.mainTimelineMode() }
|
val timelineMode = remember { timelineController.mainTimelineMode() }
|
||||||
|
|
@ -228,18 +235,26 @@ class TimelinePresenter(
|
||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(Unit) {
|
||||||
timelineItemsFactory.timelineItems
|
timelineItemsFactory.timelineItems
|
||||||
.onEach { newTimelineItems ->
|
.onEach { newTimelineItems ->
|
||||||
analyticsService.removeLongRunningTransaction(AnalyticsLongRunningTransaction.NotificationTapOpensTimeline)?.finish()
|
|
||||||
analyticsService.removeLongRunningTransaction(AnalyticsLongRunningTransaction.OpenRoom)?.finish()
|
|
||||||
timelineItemIndexer.process(newTimelineItems)
|
timelineItemIndexer.process(newTimelineItems)
|
||||||
timelineItems = newTimelineItems
|
timelineItems = newTimelineItems
|
||||||
|
|
||||||
|
analyticsService.run {
|
||||||
|
removeLongRunningTransaction(DisplayFirstTimelineItems)?.finish()
|
||||||
|
removeLongRunningTransaction(OpenRoom)?.finish()
|
||||||
|
removeLongRunningTransaction(NotificationTapOpensTimeline)?.finish()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.launchIn(this)
|
.launchIn(this)
|
||||||
|
|
||||||
combine(timelineController.timelineItems(), room.membersStateFlow) { items, membersState ->
|
combine(timelineController.timelineItems(), room.membersStateFlow) { items, membersState ->
|
||||||
|
val parent = analyticsService.getLongRunningTransaction(DisplayFirstTimelineItems)
|
||||||
|
val transaction = parent?.startChild("timelineItemsFactory.replaceWith", "Processing timeline items")
|
||||||
|
transaction?.setData("items", items.count())
|
||||||
timelineItemsFactory.replaceWith(
|
timelineItemsFactory.replaceWith(
|
||||||
timelineItems = items,
|
timelineItems = items,
|
||||||
roomMembers = membersState.roomMembers().orEmpty()
|
roomMembers = membersState.roomMembers().orEmpty()
|
||||||
)
|
)
|
||||||
|
transaction?.finish()
|
||||||
items
|
items
|
||||||
}
|
}
|
||||||
.onEach(redactedVoiceMessageManager::onEachMatrixTimelineItem)
|
.onEach(redactedVoiceMessageManager::onEachMatrixTimelineItem)
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ import io.element.android.libraries.matrix.api.roomlist.RoomListService
|
||||||
import io.element.android.libraries.matrix.api.roomlist.awaitLoaded
|
import io.element.android.libraries.matrix.api.roomlist.awaitLoaded
|
||||||
import io.element.android.libraries.matrix.impl.room.preview.RoomPreviewInfoMapper
|
import io.element.android.libraries.matrix.impl.room.preview.RoomPreviewInfoMapper
|
||||||
import io.element.android.libraries.matrix.impl.roomlist.roomOrNull
|
import io.element.android.libraries.matrix.impl.roomlist.roomOrNull
|
||||||
|
import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction
|
||||||
import io.element.android.services.analytics.api.AnalyticsService
|
import io.element.android.services.analytics.api.AnalyticsService
|
||||||
import io.element.android.services.analytics.api.recordTransaction
|
import io.element.android.services.analytics.api.recordTransaction
|
||||||
import io.element.android.services.analyticsproviders.api.recordChildTransaction
|
import io.element.android.services.analyticsproviders.api.recordChildTransaction
|
||||||
|
|
@ -113,10 +114,13 @@ class RustRoomFactory(
|
||||||
|
|
||||||
val sdkRoom = awaitRoomInRoomList(roomId) ?: return@withLock null
|
val sdkRoom = awaitRoomInRoomList(roomId) ?: return@withLock null
|
||||||
|
|
||||||
|
val parentTransaction = analyticsService.getLongRunningTransaction(AnalyticsLongRunningTransaction.OpenRoom)
|
||||||
|
|
||||||
if (sdkRoom.membership() == Membership.JOINED) {
|
if (sdkRoom.membership() == Membership.JOINED) {
|
||||||
analyticsService.recordTransaction(
|
analyticsService.recordTransaction(
|
||||||
name = "Get joined room",
|
name = "Get joined room",
|
||||||
operation = "RustRoomFactory.getJoinedRoomOrPreview",
|
operation = "RustRoomFactory.getJoinedRoomOrPreview",
|
||||||
|
parentTransaction = parentTransaction,
|
||||||
) { transaction ->
|
) { transaction ->
|
||||||
val hideThreadedEvents = featureFlagService.isFeatureEnabled(FeatureFlags.Threads)
|
val hideThreadedEvents = featureFlagService.isFeatureEnabled(FeatureFlags.Threads)
|
||||||
// Init the live timeline in the SDK from the Room
|
// Init the live timeline in the SDK from the Room
|
||||||
|
|
@ -136,9 +140,10 @@ class RustRoomFactory(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val baseRoom = transaction.recordChildTransaction(operation = "getBaseRoom", description = "Get room from SDK") { getBaseRoom(sdkRoom) }
|
||||||
GetRoomResult.Joined(
|
GetRoomResult.Joined(
|
||||||
JoinedRustRoom(
|
JoinedRustRoom(
|
||||||
baseRoom = getBaseRoom(sdkRoom),
|
baseRoom = baseRoom,
|
||||||
notificationSettingsService = notificationSettingsService,
|
notificationSettingsService = notificationSettingsService,
|
||||||
roomContentForwarder = roomContentForwarder,
|
roomContentForwarder = roomContentForwarder,
|
||||||
liveInnerTimeline = timeline,
|
liveInnerTimeline = timeline,
|
||||||
|
|
@ -152,6 +157,7 @@ class RustRoomFactory(
|
||||||
analyticsService.recordTransaction(
|
analyticsService.recordTransaction(
|
||||||
name = "Get preview of room",
|
name = "Get preview of room",
|
||||||
operation = "RustRoomFactory.getJoinedRoomOrPreview",
|
operation = "RustRoomFactory.getJoinedRoomOrPreview",
|
||||||
|
parentTransaction = parentTransaction,
|
||||||
) {
|
) {
|
||||||
val preview = try {
|
val preview = try {
|
||||||
sdkRoom.previewRoom(via = serverNames)
|
sdkRoom.previewRoom(via = serverNames)
|
||||||
|
|
|
||||||
|
|
@ -16,4 +16,7 @@ sealed class AnalyticsLongRunningTransaction(
|
||||||
data object ResumeAppUntilNewRoomsReceived : AnalyticsLongRunningTransaction("App was resumed and new room list items arrived", null)
|
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 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 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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,10 @@ interface AnalyticsService : AnalyticsTracker, ErrorTracker {
|
||||||
/**
|
/**
|
||||||
* Starts an [AnalyticsLongRunningTransaction], that can be shared with other components.
|
* 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.
|
* Gets an ongoing [AnalyticsLongRunningTransaction], if it exists.
|
||||||
|
|
@ -71,8 +74,14 @@ interface AnalyticsService : AnalyticsTracker, ErrorTracker {
|
||||||
fun removeLongRunningTransaction(longRunningTransaction: AnalyticsLongRunningTransaction): AnalyticsTransaction?
|
fun removeLongRunningTransaction(longRunningTransaction: AnalyticsLongRunningTransaction): AnalyticsTransaction?
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun <T> AnalyticsService.recordTransaction(name: String, operation: String, block: (AnalyticsTransaction) -> T): T {
|
inline fun <T> AnalyticsService.recordTransaction(
|
||||||
val transaction = startTransaction(name, operation)
|
name: String,
|
||||||
|
operation: String,
|
||||||
|
parentTransaction: AnalyticsTransaction? = null,
|
||||||
|
block: (AnalyticsTransaction) -> T
|
||||||
|
): T {
|
||||||
|
val transaction = parentTransaction?.startChild(name, operation)
|
||||||
|
?: startTransaction(name, operation)
|
||||||
try {
|
try {
|
||||||
val result = block(transaction)
|
val result = block(transaction)
|
||||||
return result
|
return result
|
||||||
|
|
|
||||||
|
|
@ -153,8 +153,13 @@ class DefaultAnalyticsService(
|
||||||
} ?: NoopAnalyticsTransaction
|
} ?: NoopAnalyticsTransaction
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun startLongRunningTransaction(longRunningTransaction: AnalyticsLongRunningTransaction): AnalyticsTransaction {
|
override fun startLongRunningTransaction(
|
||||||
val transaction = startTransaction(longRunningTransaction.name, longRunningTransaction.operation)
|
longRunningTransaction: AnalyticsLongRunningTransaction,
|
||||||
|
parentTransaction: AnalyticsTransaction?,
|
||||||
|
): AnalyticsTransaction {
|
||||||
|
val transaction = parentTransaction?.startChild(longRunningTransaction.name, longRunningTransaction.operation)
|
||||||
|
?: startTransaction(longRunningTransaction.name, longRunningTransaction.operation)
|
||||||
|
|
||||||
pendingLongRunningTransactions[longRunningTransaction] = transaction
|
pendingLongRunningTransactions[longRunningTransaction] = transaction
|
||||||
return transaction
|
return transaction
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,10 @@ class NoopAnalyticsService : AnalyticsService {
|
||||||
override fun trackError(throwable: Throwable) = Unit
|
override fun trackError(throwable: Throwable) = Unit
|
||||||
override fun updateSuperProperties(updatedProperties: SuperProperties) = Unit
|
override fun updateSuperProperties(updatedProperties: SuperProperties) = Unit
|
||||||
override fun startTransaction(name: String, operation: String?): AnalyticsTransaction = NoopAnalyticsTransaction
|
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 getLongRunningTransaction(longRunningTransaction: AnalyticsLongRunningTransaction): AnalyticsTransaction? = null
|
||||||
override fun removeLongRunningTransaction(longRunningTransaction: AnalyticsLongRunningTransaction) = NoopAnalyticsTransaction
|
override fun removeLongRunningTransaction(longRunningTransaction: AnalyticsLongRunningTransaction) = NoopAnalyticsTransaction
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,10 @@ class FakeAnalyticsService(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun startTransaction(name: String, operation: String?): AnalyticsTransaction = NoopAnalyticsTransaction
|
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
|
longRunningTransactions[longRunningTransaction] = NoopAnalyticsTransaction
|
||||||
return NoopAnalyticsTransaction
|
return NoopAnalyticsTransaction
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,9 @@ package io.element.android.services.analyticsproviders.sentry
|
||||||
|
|
||||||
import io.element.android.services.analyticsproviders.api.AnalyticsTransaction
|
import io.element.android.services.analyticsproviders.api.AnalyticsTransaction
|
||||||
import io.sentry.ISpan
|
import io.sentry.ISpan
|
||||||
|
import io.sentry.ITransaction
|
||||||
import io.sentry.Sentry
|
import io.sentry.Sentry
|
||||||
|
import timber.log.Timber
|
||||||
|
|
||||||
class SentryAnalyticsTransaction private constructor(span: ISpan) : AnalyticsTransaction {
|
class SentryAnalyticsTransaction private constructor(span: ISpan) : AnalyticsTransaction {
|
||||||
constructor(name: String, operation: String?) : this(Sentry.startTransaction(name, operation.orEmpty()))
|
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 setData(key: String, value: Any) = inner.setData(key, value)
|
||||||
override fun isFinished(): Boolean = inner.isFinished
|
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()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue