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

@ -20,6 +20,7 @@ import io.element.android.libraries.core.meta.BuildMeta
import io.element.android.libraries.core.meta.BuildType
import io.element.android.libraries.di.annotations.ApplicationContext
import io.element.android.services.analyticsproviders.api.AnalyticsProvider
import io.element.android.services.analyticsproviders.api.AnalyticsTransaction
import io.element.android.services.analyticsproviders.sentry.log.analyticsTag
import io.sentry.Breadcrumb
import io.sentry.Sentry
@ -51,6 +52,7 @@ class SentryAnalyticsProvider(
options.isEnableUserInteractionTracing = true
options.environment = buildMeta.buildType.toSentryEnv()
}
Timber.tag(analyticsTag.value).d("Sentry was initialized correctly")
}
override fun stop() {
@ -87,6 +89,10 @@ class SentryAnalyticsProvider(
override fun trackError(throwable: Throwable) {
Sentry.captureException(throwable)
}
override fun startTransaction(name: String, operation: String?): AnalyticsTransaction? {
return SentryAnalyticsTransaction(name, operation)
}
}
private fun BuildType.toSentryEnv() = when (this) {

View file

@ -0,0 +1,24 @@
/*
* 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.analyticsproviders.sentry
import io.element.android.services.analyticsproviders.api.AnalyticsTransaction
import io.sentry.ISpan
import io.sentry.Sentry
class SentryAnalyticsTransaction private constructor(span: ISpan) : AnalyticsTransaction {
constructor(name: String, operation: String?) : this(Sentry.startTransaction(name, operation.orEmpty()))
private val inner = span
override fun startChild(operation: String, description: String?): AnalyticsTransaction = SentryAnalyticsTransaction(
inner.startChild(operation, description)
)
override fun setData(key: String, value: Any) = inner.setData(key, value)
override fun isFinished(): Boolean = inner.isFinished
override fun finish() = inner.finish()
}