Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integrate Sentry Android Monitor #62

Merged
merged 1 commit into from
Aug 29, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
7 changes: 7 additions & 0 deletions .github/workflows/flaker-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ jobs:
distribution: 'zulu'
java-version: '17'

- name: Inject Secrets
env:
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
run: |
touch secrets.properties
echo "SENTRY_DSN = $SENTRY_DSN" >> secrets.properties

- name: Run detekt
run: bash ./gradlew detekt

Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@
.externalNativeBuild
.cxx
local.properties
secrets.properties
site
1 change: 1 addition & 0 deletions flaker-android-monitor/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
53 changes: 53 additions & 0 deletions flaker-android-monitor/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import org.jetbrains.kotlin.konan.properties.Properties
import java.io.FileInputStream

@Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed
plugins {
alias(libs.plugins.androidLibrary)
alias(libs.plugins.kotlinAndroid)
}

val secretsPropertiesFile = rootProject.file("secrets.properties")
val secretProperties = Properties()
secretProperties.load(FileInputStream(secretsPropertiesFile))

android {
namespace = "io.rotlabs.flakerandroidmonitor"
compileSdk = 34

buildFeatures {
buildConfig = true
}

defaultConfig {
minSdk = 24

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles("consumer-rules.pro")
buildConfigField("String", "SENTRY_DSN", "\"${secretProperties["SENTRY_DSN"]}\"")
}

buildTypes {
release {
isMinifyEnabled = false
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = "17"
}
}

dependencies {

implementation(libs.core.ktx)
implementation(libs.appcompat)
implementation(libs.sentry.android)
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.test.ext.junit)
androidTestImplementation(libs.espresso.core)
}
Empty file.
21 changes: 21 additions & 0 deletions flaker-android-monitor/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
4 changes: 4 additions & 0 deletions flaker-android-monitor/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package io.rotlabs.flakerandroidmonitor

import android.content.Context

interface FlakerMonitor {

fun initialize(appContext: Context)

fun captureException(throwable: Throwable, data: Map<String, Any?>? = null)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package io.rotlabs.flakerandroidmonitor

import android.content.Context
import io.sentry.Sentry
import io.sentry.SentryEvent
import io.sentry.SentryLevel
import io.sentry.SentryOptions
import io.sentry.android.core.SentryAndroid

class FlakerMonitorImpl : FlakerMonitor {
override fun initialize(appContext: Context) {
SentryAndroid.init(appContext) { options ->
options.dsn = BuildConfig.SENTRY_DSN
// Add a callback that will be used before the event is sent to Sentry.
// With this callback, you can modify the event or, when returning null, also discard the event.
options.beforeSend =
SentryOptions.BeforeSendCallback { event: SentryEvent, _ ->
if (SentryLevel.DEBUG == event.level) {
null
} else {
event
}
}
}
}

override fun captureException(throwable: Throwable, data: Map<String, Any?>?) {
val exceptionEvent = SentryEvent(throwable).apply {
data?.forEach { (key, value) ->
if (value != null) {
setExtra(key, value)
}
}
}
Sentry.captureEvent(exceptionEvent)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package io.rotlabs.flakerandroidmonitor.di

import android.content.Context
import io.rotlabs.flakerandroidmonitor.FlakerMonitor
import io.rotlabs.flakerandroidmonitor.FlakerMonitorImpl

open class FlakerAndroidMonitorContainer(appContext: Context) {

open val flakerMonitor: FlakerMonitor by lazy {
FlakerMonitorImpl().apply {
initialize(appContext)
}
}
}
1 change: 1 addition & 0 deletions flaker-android-okhttp/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ dependencies {
api(project(":flaker-okhttp-core"))
implementation(project(":flaker-domain"))
implementation(project(":flaker-data"))
implementation(project(":flaker-android-monitor"))

implementation(libs.core.ktx)
implementation(libs.lifecycle.runtime.ktx)
Expand Down
2 changes: 2 additions & 0 deletions flaker-android-okhttp/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,7 @@

</activity>

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

</application>
</manifest>
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import androidx.lifecycle.createSavedStateHandle
import androidx.lifecycle.viewmodel.initializer
import androidx.lifecycle.viewmodel.viewModelFactory
import io.rotlabs.di.FlakerDataContainer
import io.rotlabs.flakerandroidmonitor.FlakerMonitor
import io.rotlabs.flakerandroidmonitor.di.FlakerAndroidMonitorContainer
import io.rotlabs.flakerandroidretrofit.ui.FlakerViewModel
import io.rotlabs.flakerdb.networkrequest.NetworkRequestRepo
import io.rotlabs.flakerprefs.PrefDataStore
Expand All @@ -17,20 +19,26 @@ object FlakerAndroidOkhttpContainer {

private var prefDataStore: PrefDataStore? = null

private var flakerMonitor: FlakerMonitor? = null

private fun networkRequestRepo() = networkRequestRepo!!

private fun prefDataStore() = prefDataStore!!

private fun flakerMonitor() = flakerMonitor!!

fun install(appContext: Context) {
FlakerOkHttpCoreContainer.install(FlakerDataContainer(appContext))
val flakerAndroidMonitorContainer = FlakerAndroidMonitorContainer(appContext)
FlakerOkHttpCoreContainer.install(FlakerDataContainer(appContext), flakerAndroidMonitorContainer)
networkRequestRepo = FlakerOkHttpCoreContainer.networkRequestRepo()
prefDataStore = FlakerOkHttpCoreContainer.prefDataStore()
flakerMonitor = flakerAndroidMonitorContainer.flakerMonitor
}

fun flakerViewModelFactory(): ViewModelProvider.Factory = viewModelFactory {
initializer {
val savedStateHandle = createSavedStateHandle()
FlakerViewModel(networkRequestRepo(), prefDataStore(), savedStateHandle)
FlakerViewModel(networkRequestRepo(), prefDataStore(), flakerMonitor(), savedStateHandle)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package io.rotlabs.flakerandroidretrofit.ui

import android.util.Log
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import io.rotlabs.flakedomain.prefs.FlakerPrefs
import io.rotlabs.flakedomain.prefs.RetentionPolicy
import io.rotlabs.flakerandroidmonitor.FlakerMonitor
import io.rotlabs.flakerandroidui.components.lists.NetworkRequestUi
import io.rotlabs.flakerandroidui.screens.prefs.FlakerPrefsUiDto
import io.rotlabs.flakerandroidui.screens.search.SearchUiDto
Expand All @@ -28,6 +28,7 @@ import java.util.Locale
class FlakerViewModel(
private val networkRequestRepo: NetworkRequestRepo,
private val prefDataStore: PrefDataStore,
private val flakerMonitor: FlakerMonitor,
private val savedStateHandle: SavedStateHandle
) : ViewModel() {

Expand Down Expand Up @@ -60,7 +61,10 @@ class FlakerViewModel(

private fun observeAllRequests() {
val coroutineExceptionHandler = CoroutineExceptionHandler { _, throwable ->
Log.e("FlakerViewModel", "Error loading all requests", throwable)
flakerMonitor.captureException(
throwable,
mapOf(TAG to "Error while observing network requests: ${throwable.message}")
)
}
viewModelScope.launch(coroutineExceptionHandler) {
networkRequestRepo.observeAll()
Expand Down Expand Up @@ -127,7 +131,10 @@ class FlakerViewModel(

private fun deleteExpiredData() {
val coroutineExceptionHandler = CoroutineExceptionHandler { _, throwable ->
// TODO add firebase log
flakerMonitor.captureException(
throwable,
mapOf(TAG to "Error while deleting expired data: ${throwable.message}")
)
}
viewModelScope.launch(coroutineExceptionHandler) {
val retentionPolicy = prefDataStore.getPrefs().first().retentionPolicy
Expand Down Expand Up @@ -176,4 +183,8 @@ class FlakerViewModel(
)
}
}

companion object {
private const val TAG = "FlakerViewModel"
}
}
7 changes: 4 additions & 3 deletions flaker-okhttp-core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,14 @@ android {

dependencies {

implementation(project(":flaker-domain"))
implementation(project(":flaker-data"))
implementation(project(":flaker-android-monitor"))

implementation(libs.core.ktx)
implementation(libs.appcompat)
implementation(libs.material)

implementation(project(":flaker-domain"))
implementation(project(":flaker-data"))

implementation(libs.retrofit.mock)
implementation(libs.okttp)
testImplementation(libs.mockwebserver)
Expand Down
Loading