Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/7076.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add basic integration of Sentry to capture errors and crashes if user has given consent.
5 changes: 5 additions & 0 deletions dependencies.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ def bigImageViewer = "1.8.1"
def jjwt = "0.11.5"
def vanniktechEmoji = "0.15.0"

def sentry = "6.4.1"

def fragment = "1.5.2"

// Testing
Expand Down Expand Up @@ -165,6 +167,9 @@ ext.libs = [
apache : [
'commonsImaging' : "org.apache.sanselan:sanselan:0.97-incubator"
],
sentry: [
'sentryAndroid' : "io.sentry:sentry-android:$sentry"
],
tests : [
'kluent' : "org.amshove.kluent:kluent-android:1.68",
'timberJunitRule' : "net.lachlanmckee:timber-junit-rule:1.0.1",
Expand Down
1 change: 1 addition & 0 deletions dependencies_groups.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ ext.groups = [
'io.opencensus',
'io.reactivex.rxjava2',
'io.realm',
'io.sentry',
'it.unimi.dsi',
'jakarta.activation',
'jakarta.xml.bind',
Expand Down
14 changes: 12 additions & 2 deletions vector-config/src/main/java/im/vector/app/config/Analytics.kt
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ sealed interface Analytics {
object Disabled : Analytics

/**
* Analytics integration via PostHog.
* Analytics integration via PostHog and Sentry.
*/
data class PostHog(
data class Enabled(
/**
* The PostHog instance url.
*/
Expand All @@ -44,5 +44,15 @@ sealed interface Analytics {
* A URL to more information about the analytics collection.
*/
val policyLink: String,

/**
* The Sentry DSN url.
*/
val sentryDSN: String,

/**
* Environment for Sentry.
*/
val sentryEnvironment: String
) : Analytics
}
10 changes: 7 additions & 3 deletions vector-config/src/main/java/im/vector/app/config/Config.kt
Original file line number Diff line number Diff line change
Expand Up @@ -68,25 +68,29 @@ object Config {
* The analytics configuration to use for the Debug build type.
* Can be disabled by providing Analytics.Disabled
*/
val DEBUG_ANALYTICS_CONFIG = Analytics.PostHog(
val DEBUG_ANALYTICS_CONFIG = Analytics.Enabled(
postHogHost = "https://posthog.element.dev",
postHogApiKey = "phc_VtA1L35nw3aeAtHIx1ayrGdzGkss7k1xINeXcoIQzXN",
policyLink = "https://element.io/cookie-policy",
sentryDSN = "https://f6acc9cfc2024641b28c87ad95e73e66@sentry.tools.element.io/49",
sentryEnvironment = "DEBUG"
)

/**
* The analytics configuration to use for the Release build type.
* Can be disabled by providing Analytics.Disabled
*/
val RELEASE_ANALYTICS_CONFIG = Analytics.PostHog(
val RELEASE_ANALYTICS_CONFIG = Analytics.Enabled(
postHogHost = "https://posthog.hss.element.io",
postHogApiKey = "phc_Jzsm6DTm6V2705zeU5dcNvQDlonOR68XvX2sh1sEOHO",
policyLink = "https://element.io/cookie-policy",
sentryDSN = "https://f6acc9cfc2024641b28c87ad95e73e66@sentry.tools.element.io/49",
sentryEnvironment = "RELEASE"
)

/**
* The analytics configuration to use for the Nightly build type.
* Can be disabled by providing Analytics.Disabled
*/
val NIGHTLY_ANALYTICS_CONFIG = RELEASE_ANALYTICS_CONFIG
val NIGHTLY_ANALYTICS_CONFIG = RELEASE_ANALYTICS_CONFIG.copy(sentryEnvironment = "NIGHTLY")
}
1 change: 1 addition & 0 deletions vector/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ dependencies {

// Analytics
implementation 'com.posthog.android:posthog:1.1.2'
implementation libs.sentry.sentryAndroid

// UnifiedPush
implementation 'com.github.UnifiedPush:android-connector:2.0.1'
Expand Down
3 changes: 3 additions & 0 deletions vector/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@

<application android:supportsRtl="true">

<!-- Sentry auto-initialization disable -->
<meta-data android:name="io.sentry.auto-init" android:value="false" />

<!-- No limit for screen ratio: avoid black strips -->
<meta-data
android:name="android.max_aspect"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,14 @@ object ConfigurationModule {
else -> throw IllegalStateException("Unhandled build type: ${BuildConfig.BUILD_TYPE}")
}
return when (config) {
Analytics.Disabled -> AnalyticsConfig(isEnabled = false, "", "", "")
is Analytics.PostHog -> AnalyticsConfig(
Analytics.Disabled -> AnalyticsConfig(isEnabled = false, "", "", "", "", "")
is Analytics.Enabled -> AnalyticsConfig(
isEnabled = true,
postHogHost = config.postHogHost,
postHogApiKey = config.postHogApiKey,
policyLink = config.policyLink
policyLink = config.policyLink,
sentryDSN = config.sentryDSN,
sentryEnvironment = config.sentryEnvironment
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,6 @@ data class AnalyticsConfig(
val postHogHost: String,
val postHogApiKey: String,
val policyLink: String,
val sentryDSN: String,
val sentryEnvironment: String
)
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ private val IGNORED_OPTIONS: Options? = null
@Singleton
class DefaultVectorAnalytics @Inject constructor(
postHogFactory: PostHogFactory,
private val sentryFactory: SentryFactory,
analyticsConfig: AnalyticsConfig,
private val analyticsStore: AnalyticsStore,
private val lateInitUserPropertiesFactory: LateInitUserPropertiesFactory,
Expand Down Expand Up @@ -123,10 +124,18 @@ class DefaultVectorAnalytics @Inject constructor(
Timber.tag(analyticsTag.value).d("User consent updated to $consent")
userConsent = consent
optOutPostHog()
initOrStopSentry(consent)
}
.launchIn(globalScope)
}

private fun initOrStopSentry(userConsent: Boolean) {
Comment thread
amitkma marked this conversation as resolved.
Outdated
when (userConsent) {
true -> sentryFactory.initSentry()
false -> sentryFactory.stopSentry()
}
}

private fun optOutPostHog() {
userConsent?.let { posthog?.optOut(!it) }
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright (c) 2022 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package im.vector.app.features.analytics.impl

import android.content.Context
import im.vector.app.features.analytics.AnalyticsConfig
import im.vector.app.features.analytics.log.analyticsTag
import io.sentry.Sentry
import io.sentry.SentryOptions
import io.sentry.android.core.SentryAndroid
import timber.log.Timber
import javax.inject.Inject

class SentryFactory @Inject constructor(
private val context: Context,
private val analyticsConfig: AnalyticsConfig,
) {

fun initSentry() {
Timber.tag(analyticsTag.value).d("Initializing Sentry")
if (Sentry.isEnabled()) return
SentryAndroid.init(context) { options ->
options.dsn = analyticsConfig.sentryDSN
options.beforeSend = SentryOptions.BeforeSendCallback { event, _ -> event }
options.tracesSampleRate = 1.0
options.isEnableUserInteractionTracing = true
Comment thread
amitkma marked this conversation as resolved.
options.environment = analyticsConfig.sentryEnvironment
options.diagnosticLevel
}
}

fun stopSentry() {
Timber.tag(analyticsTag.value).d("Stopping Sentry")
Sentry.close()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import im.vector.app.test.fixtures.AnalyticsConfigFixture.anAnalyticsConfig
import im.vector.app.test.fixtures.aUserProperties
import im.vector.app.test.fixtures.aVectorAnalyticsEvent
import im.vector.app.test.fixtures.aVectorAnalyticsScreen
import io.mockk.mockk
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
Expand All @@ -48,6 +49,7 @@ class DefaultVectorAnalyticsTest {

private val defaultVectorAnalytics = DefaultVectorAnalytics(
postHogFactory = FakePostHogFactory(fakePostHog.instance).instance,
sentryFactory = mockk(),
analyticsStore = fakeAnalyticsStore.instance,
globalScope = CoroutineScope(Dispatchers.Unconfined),
analyticsConfig = anAnalyticsConfig(isEnabled = true),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ object AnalyticsConfigFixture {
isEnabled: Boolean = false,
postHogHost: String = "http://posthog.url",
postHogApiKey: String = "api-key",
policyLink: String = "http://policy.link"
) = AnalyticsConfig(isEnabled, postHogHost, postHogApiKey, policyLink)
policyLink: String = "http://policy.link",
sentryDSN: String = "http://sentry.dsn",
sentryEnvironment: String = "sentry-env"
) = AnalyticsConfig(isEnabled, postHogHost, postHogApiKey, policyLink, sentryDSN, sentryEnvironment)
}