1
0
Fork 0

Closes #5091: Refactor Sentry BreadCrumbs to use lib-crash BreadCrumbs

master
Roger Yang 2019-09-03 17:47:43 -04:00 committed by Emily Kager
parent 80d8c76453
commit b3eca65614
4 changed files with 77 additions and 22 deletions

View File

@ -35,9 +35,8 @@ import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.browser.browsingmode.BrowsingModeManager import org.mozilla.fenix.browser.browsingmode.BrowsingModeManager
import org.mozilla.fenix.browser.browsingmode.DefaultBrowsingModeManager import org.mozilla.fenix.browser.browsingmode.DefaultBrowsingModeManager
import org.mozilla.fenix.components.FenixSnackbar import org.mozilla.fenix.components.FenixSnackbar
import org.mozilla.fenix.components.isSentryEnabled
import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.components.metrics.SentryBreadcrumbsRecorder import org.mozilla.fenix.components.metrics.BreadcrumbsRecorder
import org.mozilla.fenix.exceptions.ExceptionsFragmentDirections import org.mozilla.fenix.exceptions.ExceptionsFragmentDirections
import org.mozilla.fenix.ext.alreadyOnDestination import org.mozilla.fenix.ext.alreadyOnDestination
import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.components
@ -96,9 +95,8 @@ open class HomeActivity : AppCompatActivity(), ShareFragment.TabsSharedCallback
setupToolbarAndNavigation() setupToolbarAndNavigation()
if (settings.isTelemetryEnabled) { if (settings.isTelemetryEnabled) {
if (isSentryEnabled()) { lifecycle.addObserver(BreadcrumbsRecorder(components.analytics.crashReporter,
lifecycle.addObserver(SentryBreadcrumbsRecorder(navHost.navController, ::getSentryBreadcrumbMessage)) navHost.navController, ::getBreadcrumbMessage))
}
intent intent
?.toSafeIntent() ?.toSafeIntent()
@ -157,7 +155,7 @@ open class HomeActivity : AppCompatActivity(), ShareFragment.TabsSharedCallback
super.onBackPressed() super.onBackPressed()
} }
protected open fun getSentryBreadcrumbMessage(destination: NavDestination): String { protected open fun getBreadcrumbMessage(destination: NavDestination): String {
val fragmentName = resources.getResourceEntryName(destination.id) val fragmentName = resources.getResourceEntryName(destination.id)
return "Changing to fragment $fragmentName, isCustomTab: false" return "Changing to fragment $fragmentName, isCustomTab: false"
} }

View File

@ -10,27 +10,24 @@ import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.OnLifecycleEvent import androidx.lifecycle.OnLifecycleEvent
import androidx.navigation.NavController import androidx.navigation.NavController
import androidx.navigation.NavDestination import androidx.navigation.NavDestination
import io.sentry.Sentry import mozilla.components.lib.crash.Breadcrumb
import io.sentry.event.Breadcrumb import mozilla.components.lib.crash.CrashReporter
import io.sentry.event.BreadcrumbBuilder
import org.mozilla.fenix.components.isSentryEnabled
/** /**
* Records breadcrumbs in Sentry when the fragment changes. * Records breadcrumbs when the fragment changes.
* *
* Should be registered as a [LifecycleObserver] on an activity if telemetry is enabled. * Should be registered as a [LifecycleObserver] on an activity if telemetry is enabled.
* It will automatically be removed when the lifecycle owner is destroyed. * It will automatically be removed when the lifecycle owner is destroyed.
*/ */
class SentryBreadcrumbsRecorder( class BreadcrumbsRecorder(
private val crashReporter: CrashReporter,
private val navController: NavController, private val navController: NavController,
private val getBreadcrumbMessage: (NavDestination) -> String private val getBreadcrumbMessage: (NavDestination) -> String
) : NavController.OnDestinationChangedListener, LifecycleObserver { ) : NavController.OnDestinationChangedListener, LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE) @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
fun onCreate() { fun onCreate() {
if (isSentryEnabled()) { navController.addOnDestinationChangedListener(this)
navController.addOnDestinationChangedListener(this)
}
} }
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
@ -46,12 +43,12 @@ class SentryBreadcrumbsRecorder(
destination: NavDestination, destination: NavDestination,
arguments: Bundle? arguments: Bundle?
) { ) {
Sentry.getContext().recordBreadcrumb( crashReporter.recordCrashBreadcrumb(
BreadcrumbBuilder() Breadcrumb(
.setCategory("DestinationChanged") message = getBreadcrumbMessage(destination),
.setMessage(getBreadcrumbMessage(destination)) category = "DestinationChanged",
.setLevel(Breadcrumb.Level.INFO) level = Breadcrumb.Level.INFO
.build() )
) )
} }
} }

View File

@ -18,7 +18,7 @@ import org.mozilla.fenix.theme.CustomTabThemeManager
import java.security.InvalidParameterException import java.security.InvalidParameterException
open class CustomTabActivity : HomeActivity() { open class CustomTabActivity : HomeActivity() {
final override fun getSentryBreadcrumbMessage(destination: NavDestination): String { final override fun getBreadcrumbMessage(destination: NavDestination): String {
val fragmentName = resources.getResourceEntryName(destination.id) val fragmentName = resources.getResourceEntryName(destination.id)
return "Changing to fragment $fragmentName, isCustomTab: true" return "Changing to fragment $fragmentName, isCustomTab: true"
} }

View File

@ -0,0 +1,60 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.fenix.components.metrics
import androidx.navigation.NavController
import androidx.navigation.NavDestination
import androidx.test.ext.junit.runners.AndroidJUnit4
import kotlinx.coroutines.ObsoleteCoroutinesApi
import mozilla.components.lib.crash.Breadcrumb
import mozilla.components.lib.crash.Crash
import mozilla.components.lib.crash.CrashReporter
import mozilla.components.lib.crash.service.CrashReporterService
import mozilla.components.support.test.mock
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito.spy
import org.mockito.Mockito.verify
import org.mozilla.fenix.TestApplication
import org.robolectric.annotation.Config
@ObsoleteCoroutinesApi
@RunWith(AndroidJUnit4::class)
@Config(application = TestApplication::class)
internal class BreadcrumbRecorderTest {
@Test
fun `ensure crash reporter recordCrashBreadcrumb is called`() {
val service = object : CrashReporterService {
override fun report(crash: Crash.UncaughtExceptionCrash) {
}
override fun report(crash: Crash.NativeCodeCrash) {
}
}
val reporter = spy(CrashReporter(
services = listOf(service),
shouldPrompt = CrashReporter.Prompt.NEVER
))
fun getBreadcrumbMessage(@Suppress("UNUSED_PARAMETER") destination: NavDestination): String {
return "test"
}
val navController: NavController = mock()
val navDestination: NavDestination = mock()
val breadcrumb = Breadcrumb(
message = getBreadcrumbMessage(navDestination),
category = "DestinationChanged",
level = Breadcrumb.Level.INFO
)
val breadCrumbRecorder = BreadcrumbsRecorder(reporter, navController, ::getBreadcrumbMessage)
breadCrumbRecorder.onDestinationChanged(navController, navDestination, null)
verify(reporter).recordCrashBreadcrumb(breadcrumb)
}
}