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:
Jorge Martin Espinosa 2025-11-19 12:42:55 +01:00 committed by GitHub
parent c8604c262a
commit f78c80803b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
25 changed files with 245 additions and 41 deletions

View file

@ -0,0 +1,15 @@
/*
* Copyright (c) 2025 Element Creations Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.services.analytics.api
sealed class AnalyticsLongRunningTransaction(
val name: String,
val operation: String?,
) {
data object FirstRoomsDisplayed : AnalyticsLongRunningTransaction("First rooms displayed after login or restoration", null)
}

View file

@ -9,6 +9,7 @@
package io.element.android.services.analytics.api
import io.element.android.services.analyticsproviders.api.AnalyticsProvider
import io.element.android.services.analyticsproviders.api.AnalyticsTransaction
import io.element.android.services.analyticsproviders.api.trackers.AnalyticsTracker
import io.element.android.services.analyticsproviders.api.trackers.ErrorTracker
import kotlinx.coroutines.flow.Flow
@ -48,4 +49,23 @@ interface AnalyticsService : AnalyticsTracker, ErrorTracker {
* Update analyticsId from the AccountData.
*/
suspend fun setAnalyticsId(analyticsId: String)
/**
* Starts a transaction to measure the performance of an operation.
*/
fun startTransaction(name: String, operation: String? = null): AnalyticsTransaction
fun startLongRunningTransaction(longRunningTransaction: AnalyticsLongRunningTransaction)
fun stopLongRunningTransaction(longRunningTransaction: AnalyticsLongRunningTransaction)
}
inline fun <T> AnalyticsService.recordTransaction(name: String, operation: String, block: (AnalyticsTransaction) -> T): T {
val transaction = startTransaction(name, operation)
try {
val result = block(transaction)
return result
} finally {
transaction.finish()
}
}

View file

@ -0,0 +1,17 @@
/*
* Copyright (c) 2025 Element Creations Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.services.analytics.api
import io.element.android.services.analyticsproviders.api.AnalyticsTransaction
object NoopAnalyticsTransaction : AnalyticsTransaction {
override fun startChild(operation: String, description: String?): AnalyticsTransaction = NoopAnalyticsTransaction
override fun setData(key: String, value: Any) {}
override fun isFinished(): Boolean = true
override fun finish() {}
}