Commit a7887fe0 authored by Daniel Wolf's avatar Daniel Wolf
Browse files

Add a Sentry config server which can be used to dynamically provide a Sentry DSN

parent a58f51b6
......@@ -18,7 +18,8 @@ android {
buildConfigField("Boolean", "FROM_CI", String.valueOf(getSystemVariableOrDefault("CI_COMMIT_SHORT_SHA", "") != ""))
buildConfigField("String", "COMMIT_HASH", '"' + getGitCommitHash() + '"')
buildConfigField("String", "SENTRY_DSN", '""')
buildConfigField("String", "SENTRY_DSN", '"dummy"') // A valid Sentry DSN, or "dummy"
buildConfigField("String", "SENTRY_DSN_CONFIGSERVER", '"dummy"') // A host which returns a valid Sentry DSN on GET, or "dummy". If both are dummy Sentry is disabled.
buildConfigField("Boolean", "SHOW_DOQ", 'false')
buildConfigField("Boolean", "SHOW_INTRO", 'false')
buildConfigField("Boolean", "IN_APP_UPDATES", "false")
......
......@@ -24,15 +24,13 @@ import io.sentry.Sentry
import io.sentry.SentryOptions
import io.sentry.android.core.*
import io.sentry.protocol.User
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import okhttp3.*
import org.minidns.dnsmessage.DnsMessage
import org.minidns.dnsmessage.Question
import org.minidns.record.A
import org.minidns.record.AAAA
import org.minidns.record.Record
import java.net.InetAddress
import java.io.IOException
import java.util.*
import kotlin.system.exitProcess
......@@ -172,22 +170,27 @@ class SmokeScreen : Application() {
}
fun initSentry(forceStatus: Status = Status.NONE) {
if (!BuildConfig.DEBUG && BuildConfig.SENTRY_DSN != "dummy") {
log("Sentry will be initialized.")
GlobalScope.launch(Dispatchers.IO) {
val enabledType = getPreferences().crashreportingType
if (forceStatus == Status.NONE &&
enabledType == Crashreporting.OFF) return
log("Maybe initializing Sentry")
getSentryDSN { resolvedDSN ->
log("Initializing Sentry.")
sentryReady = false
try {
val hostName = InetAddress.getLocalHost().hostName
if(!hostName.startsWith("mars-sandbox", true)) {
val enabledType = getPreferences().crashreportingType
if (sentryReady) {
log("Reinitializing Sentry with new DSN")
SentryAndroid.init(this@SmokeScreen) {
it.dsn = resolvedDSN
}
} else {
if (forceStatus != Status.DATASAVING && (enabledType == Crashreporting.FULL || forceStatus == Status.ENABLED)) {
// Enable Sentry in full mode
// This passes some device-related data, but nothing which allows user actions to be tracked across the app
// Info: Some data is attached by the AndroidEventBuilderHelper class, which is present by default
SentryAndroid.init(this@SmokeScreen) {
it.dsn = BuildConfig.SENTRY_DSN
it.dsn = resolvedDSN
}
Sentry.setUser(User().apply {
this.username = getPreferences().crashReportingUUID
......@@ -223,7 +226,7 @@ class SmokeScreen : Application() {
// Only data absolutely necessary is transmitted (Android version, app version).
// Only crashes will be reported, no regular events.
SentryAndroid.init(this@SmokeScreen) {
it.dsn = BuildConfig.SENTRY_DSN
it.dsn = resolvedDSN
setupSentryForDatasaving(it)
}
Sentry.setUser(User().apply {
......@@ -236,11 +239,52 @@ class SmokeScreen : Application() {
sentryReady = true
}
}
} catch(ex:Throwable) {
ex.printStackTrace()
}
log("Sentry ready.")
} catch (ex: Throwable) {
log("Creating Sentry errored")
log(ex)
}
}
}
private fun getSentryDSN(then:(dsn:String) -> Unit) {
try {
val primaryDSN = BuildConfig.SENTRY_DSN
val configServer = BuildConfig.SENTRY_DSN_CONFIGSERVER
if(primaryDSN.contains("@")) then(primaryDSN)
else log("Primary Sentry DSN not set, maybe retrieving from server")
if(configServer.isNotBlank() && configServer.startsWith("http") && !configServer.contains("@")) {
log("Dynamically retrieving Sentry DSN from $configServer")
val request = Request.Builder().url(configServer).build()
OkHttpClient.Builder().build().newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
log("Sentry DSN retrieval failed with error: ${e.message}")
}
override fun onResponse(call: Call, response: Response) {
println("RESPONSE")
if (!response.isSuccessful) {
log("Sentry DSN retrieval failed with status ${response.code}")
}
val retrievedDSN = response.body?.string()?.trim()
if (retrievedDSN.isNullOrBlank() || !retrievedDSN.contains("@") || !retrievedDSN.startsWith(
"http"
)
) {
log("Sentry DSN retrieval returned invalid DSN '$retrievedDSN'.")
} else {
if (true || retrievedDSN != primaryDSN) {
log("Sentry DSN successfuly resolved to '$retrievedDSN'")
then(retrievedDSN)
} else log("Retrieved Sentry DSN is the same as configured DSN, not re-configuring")
}
}
})
}
} catch (ex:Throwable) {
log("Getting Sentry DSN errorerd")
log(ex)
}
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment