Add some performance metrics for Sentry (#5760)
- Add `AnalyticsService.startTransaction(...)` to start a logging transaction that can be uploaded to Sentry if the user enabled the analytics upload. - Add `AnalyticsTransaction` wrapper to abstract the Sentry ones. - Added several helper methods to improve the UX around these transactions. - Then measure: - Time until the first sync, and how it ended. - Time until the first rooms are displayed. - Time to load a room or a preview. - Time to load a timeline.
This commit is contained in:
committed by
GitHub
parent
de3ffca1af
commit
c6c2f4a267
@@ -90,6 +90,8 @@ import io.element.android.libraries.matrix.api.verification.VerificationRequest
|
||||
import io.element.android.libraries.preferences.api.store.AppPreferencesStore
|
||||
import io.element.android.libraries.push.api.notifications.conversations.NotificationConversationService
|
||||
import io.element.android.libraries.ui.common.nodes.emptyNode
|
||||
import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction
|
||||
import io.element.android.services.analytics.api.AnalyticsService
|
||||
import io.element.android.services.appnavstate.api.AppNavigationStateService
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.first
|
||||
@@ -136,6 +138,7 @@ class LoggedInFlowNode(
|
||||
private val appPreferencesStore: AppPreferencesStore,
|
||||
private val buildMeta: BuildMeta,
|
||||
snackbarDispatcher: SnackbarDispatcher,
|
||||
private val analyticsService: AnalyticsService,
|
||||
) : BaseFlowNode<LoggedInFlowNode.NavTarget>(
|
||||
backstack = BackStack(
|
||||
initialElement = NavTarget.Placeholder,
|
||||
@@ -212,6 +215,8 @@ class LoggedInFlowNode(
|
||||
matrixClient.getMaxFileUploadSize()
|
||||
}
|
||||
|
||||
analyticsService.startLongRunningTransaction(AnalyticsLongRunningTransaction.FirstRoomsDisplayed)
|
||||
|
||||
ftueService.state
|
||||
.onEach { ftueState ->
|
||||
when (ftueState) {
|
||||
|
||||
@@ -18,6 +18,8 @@ import io.element.android.libraries.core.coroutine.CoroutineDispatchers
|
||||
import io.element.android.libraries.core.coroutine.childScope
|
||||
import io.element.android.libraries.matrix.api.sync.SyncService
|
||||
import io.element.android.libraries.matrix.api.sync.SyncState
|
||||
import io.element.android.services.analytics.api.AnalyticsService
|
||||
import io.element.android.services.analytics.api.recordTransaction
|
||||
import io.element.android.services.appnavstate.api.AppForegroundStateService
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.FlowPreview
|
||||
@@ -39,6 +41,7 @@ class SyncOrchestrator(
|
||||
private val appForegroundStateService: AppForegroundStateService,
|
||||
private val networkMonitor: NetworkMonitor,
|
||||
dispatchers: CoroutineDispatchers,
|
||||
private val analyticsService: AnalyticsService,
|
||||
) {
|
||||
@AssistedFactory
|
||||
interface Factory {
|
||||
@@ -69,10 +72,13 @@ class SyncOrchestrator(
|
||||
// Perform an initial sync if the sync service is not running, to check whether the homeserver is accessible
|
||||
// Otherwise, if the device is offline the sync service will never start and the SyncState will be Idle, not Offline
|
||||
Timber.tag(tag).d("performing initial sync attempt")
|
||||
syncService.startSync()
|
||||
analyticsService.recordTransaction("First sync", "syncService.startSync()") { transaction ->
|
||||
syncService.startSync()
|
||||
|
||||
// Wait until the sync service is not idle, either it will be running or in error/offline state
|
||||
syncService.syncState.first { it != SyncState.Idle }
|
||||
// Wait until the sync service is not idle, either it will be running or in error/offline state
|
||||
val firstState = syncService.syncState.first { it != SyncState.Idle }
|
||||
transaction.setData("first_sync_state", firstState.name)
|
||||
}
|
||||
|
||||
observeStates()
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import io.element.android.features.networkmonitor.api.NetworkStatus
|
||||
import io.element.android.features.networkmonitor.test.FakeNetworkMonitor
|
||||
import io.element.android.libraries.matrix.api.sync.SyncState
|
||||
import io.element.android.libraries.matrix.test.sync.FakeSyncService
|
||||
import io.element.android.services.analytics.test.FakeAnalyticsService
|
||||
import io.element.android.services.appnavstate.test.FakeAppForegroundStateService
|
||||
import io.element.android.tests.testutils.WarmUpRule
|
||||
import io.element.android.tests.testutils.lambda.lambdaRecorder
|
||||
@@ -390,5 +391,6 @@ class SyncOrchestratorTest {
|
||||
networkMonitor = networkMonitor,
|
||||
appForegroundStateService = appForegroundStateService,
|
||||
dispatchers = testCoroutineDispatchers(),
|
||||
analyticsService = FakeAnalyticsService(),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import io.element.android.libraries.matrix.api.sync.SyncService
|
||||
import io.element.android.libraries.matrix.test.A_SESSION_ID
|
||||
import io.element.android.libraries.matrix.test.FakeMatrixClient
|
||||
import io.element.android.libraries.matrix.test.auth.FakeMatrixAuthenticationService
|
||||
import io.element.android.services.analytics.test.FakeAnalyticsService
|
||||
import io.element.android.services.appnavstate.test.FakeAppForegroundStateService
|
||||
import io.element.android.tests.testutils.testCoroutineDispatchers
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
@@ -129,6 +130,7 @@ class MatrixSessionCacheTest {
|
||||
appForegroundStateService = FakeAppForegroundStateService(),
|
||||
networkMonitor = FakeNetworkMonitor(),
|
||||
dispatchers = testCoroutineDispatchers(),
|
||||
analyticsService = FakeAnalyticsService(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user