Replace Crashlytics with Sentry

Signed-off-by: William Brawner <me@wbrawner.com>
This commit is contained in:
William Brawner 2020-06-10 10:16:53 -07:00
parent 0e70364c6e
commit 1cc0063b15
11 changed files with 59 additions and 31 deletions

1
.gitignore vendored
View file

@ -12,3 +12,4 @@
*.log
keystore.properties
*.jks
sentry.properties

View file

@ -3,7 +3,7 @@ apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: 'jacoco'
apply plugin: 'com.google.firebase.crashlytics'
apply plugin: 'io.sentry.android.gradle'
def keystoreProperties = new Properties()
try {
@ -44,6 +44,9 @@ android {
versionCode 26
versionName "0.8.4"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
manifestPlaceholders = [
sentryDsn: "https://399270639b2e4b10a028a2be9192d1d3@sentry.brawner.dev/2"
]
buildConfigField "boolean", "ENABLE_CUSTOM_CSS", "false"
}
signingConfigs {
@ -99,11 +102,10 @@ dependencies {
implementation 'com.commonsware.cwac:anddown:0.3.0'
implementation 'com.android.billingclient:billing:2.2.0'
implementation 'com.google.firebase:firebase-core:17.3.0'
implementation 'com.google.firebase:firebase-crashlytics:17.0.0-beta04'
implementation 'com.google.firebase:firebase-analytics:17.3.0'
implementation "androidx.core:core-ktx:1.2.0"
implementation 'androidx.browser:browser:1.2.0'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'io.sentry:sentry-android:2.1.6'
def coroutines_version = "1.3.0-RC2"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"
@ -117,6 +119,7 @@ dependencies {
apply plugin: 'com.google.gms.google-services'
repositories {
mavenCentral()
jcenter()
}
jacoco {

View file

@ -67,7 +67,10 @@
<activity android:name=".view.activity.SupportActivity" />
<meta-data
android:name="firebase_crashlytics_collection_enabled"
android:name="io.sentry.dsn"
android:value="${sentryDsn}" />
<meta-data
android:name="io.sentry.auto-init"
android:value="false" />
</application>

View file

@ -3,11 +3,10 @@
First and foremost, Simple Markdown DOES NOT collect any personally identifiable information. The
internet access permission is requested primarily for retrieving images from the internet in
case you embed them in your markdown, but it also allows me to send automated error and crash
reports to myself whenever the app runs into an issue. These error reports are opt-out, and are
powered by [Firebase Crashlytics] (https://firebase.google.com/docs/crashlytics/), which is a
free error reporting solution provided by Google. These error reports are used exclusively for
fixing problems that occur while you're using the app, along with some analytics info like how
long you use the app for, how often, and which features of the app you use. This helps me to
determine how to spend my very limited time on building out new features. I'll have to defer to
[Google's Privacy Policy](https://policies.google.com/privacy) to explain how they handle the
data. As for me, I don't knowingly or willingly sell or trade your data.
reports to myself whenever the app runs into an issue. These automated reports are powered by my own
self-hosted version of [Sentry] (https://sentry.io/), which is a free and open source error
reporting solution. These error reports are used exclusively for fixing problems that occur while
you're using the app. For more information on the kinds of data that may be sent in these automated
error reports, please see the [relevant documentation](https://docs.sentry.io/platforms/android/#context)
on Sentry's website. If you would like to opt-out of these error reports, please visit the in-app
settings page to disable the toggle for error reports.

View file

@ -2,15 +2,19 @@ package com.wbrawner.simplemarkdown
import android.app.Application
import android.os.StrictMode
import com.wbrawner.simplemarkdown.utility.CrashlyticsErrorHandler
import androidx.preference.PreferenceManager
import com.wbrawner.simplemarkdown.utility.ErrorHandler
import com.wbrawner.simplemarkdown.utility.SentryErrorHandler
class MarkdownApplication : Application() {
val errorHandler: ErrorHandler by lazy {
CrashlyticsErrorHandler()
SentryErrorHandler()
}
override fun onCreate() {
val enableErrorReports = PreferenceManager.getDefaultSharedPreferences(this)
.getBoolean(getString(R.string.error_reports_enabled), true)
errorHandler.init(this, enableErrorReports)
if (BuildConfig.DEBUG) {
StrictMode.setThreadPolicy(StrictMode.ThreadPolicy.Builder()
.detectAll()

View file

@ -1,27 +1,44 @@
package com.wbrawner.simplemarkdown.utility
import android.content.Context
import android.util.Log
import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.wbrawner.simplemarkdown.BuildConfig
import io.sentry.android.core.SentryAndroid
import io.sentry.core.Sentry
import java.util.concurrent.atomic.AtomicBoolean
interface ErrorHandler {
fun init(context: Context, enable: Boolean)
fun enable(enable: Boolean)
fun reportException(t: Throwable, message: String? = null)
}
class CrashlyticsErrorHandler : ErrorHandler {
private val crashlytics = FirebaseCrashlytics.getInstance()
class SentryErrorHandler : ErrorHandler {
private lateinit var enabled: AtomicBoolean
override fun init(context: Context, enable: Boolean) {
enabled = AtomicBoolean(enable)
SentryAndroid.init(context) { options ->
options.setBeforeSend { event, _ ->
if (enabled.get()) {
event
} else {
null
}
}
}
}
override fun enable(enable: Boolean) {
crashlytics.setCrashlyticsCollectionEnabled(enable)
enabled.set(enable)
}
override fun reportException(t: Throwable, message: String?) {
@Suppress("ConstantConditionIf")
if (BuildConfig.DEBUG) {
Log.e("CrashlyticsErrorHandler", "Caught exception: $message", t)
Log.e("SentryErrorHandler", "Caught exception: $message", t)
return
}
crashlytics.recordException(t)
Sentry.captureException(t)
}
}

View file

@ -3,7 +3,6 @@ package com.wbrawner.simplemarkdown.view.activity
import android.os.Bundle
import android.view.MenuItem
import androidx.appcompat.app.AppCompatActivity
import com.wbrawner.simplemarkdown.R
class SettingsActivity : AppCompatActivity() {
@ -12,9 +11,7 @@ class SettingsActivity : AppCompatActivity() {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_settings)
setSupportActionBar(findViewById(R.id.toolbar))
if (supportActionBar != null) {
supportActionBar!!.setDisplayHomeAsUpEnabled(true)
}
supportActionBar?.setDisplayHomeAsUpEnabled(true)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {

View file

@ -34,7 +34,7 @@
<string name="action_lock_swipe">Lock Swiping</string>
<string name="action_select">Select</string>
<string name="action_privacy">Privacy</string>
<string name="error_reports_enabled">crashlytics.enable</string>
<string name="error_reports_enabled">errors.enable</string>
<string name="pref_title_error_reports">Enable automated error reports</string>
<string name="pref_error_reports_off">Error reports will not be sent</string>
<string name="pref_error_reports_on">Error reports will be sent</string>

View file

@ -7,9 +7,9 @@ buildscript {
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.6.3'
classpath 'com.android.tools.build:gradle:4.0.0'
classpath 'com.google.gms:google-services:4.3.3'
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.0.0-beta04'
classpath 'io.sentry:sentry-android-gradle-plugin:1.7.34'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}

View file

@ -1,6 +1,6 @@
#Thu Mar 19 08:56:07 CST 2020
#Wed Jun 10 07:53:53 MST 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip

4
sentry.properties.sample Normal file
View file

@ -0,0 +1,4 @@
defaults.url=https://sentry.brawner.dev/
defaults.project=simplemarkdown
defaults.org=wbrawner
auth.token=