Skip to content

Commit 56a3320

Browse files
committed
Configure Sentry crash reporting
1 parent 7bba0fb commit 56a3320

File tree

6 files changed

+120
-1
lines changed

6 files changed

+120
-1
lines changed

composeApp/src/commonMain/kotlin/org/ooni/probe/App.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,14 @@ fun App(
7878
}
7979
}
8080

81+
Logger.addLogWriter(dependencies.crashMonitoring.logWriter)
82+
8183
LaunchedEffect(Unit) {
8284
logAppStart(dependencies)
8385
}
86+
LaunchedEffect(Unit) {
87+
dependencies.crashMonitoring.setup()
88+
}
8489
LaunchedEffect(Unit) {
8590
dependencies.bootstrapTestDescriptors()
8691
dependencies.bootstrapPreferences()

composeApp/src/commonMain/kotlin/org/ooni/probe/di/Dependencies.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ import org.ooni.probe.domain.ShouldShowVpnWarning
6464
import org.ooni.probe.domain.TestRunStateManager
6565
import org.ooni.probe.domain.UploadMissingMeasurements
6666
import org.ooni.probe.shared.PlatformInfo
67+
import org.ooni.probe.shared.monitoring.CrashMonitoring
6768
import org.ooni.probe.ui.dashboard.DashboardViewModel
6869
import org.ooni.probe.ui.descriptor.DescriptorViewModel
6970
import org.ooni.probe.ui.descriptor.add.AddDescriptorViewModel
@@ -116,6 +117,10 @@ class Dependencies(
116117
private val writeFile: WriteFile by lazy { WriteFileOkio(FileSystem.SYSTEM, baseFileDir) }
117118
private val deleteFiles: DeleteFiles by lazy { DeleteFilesOkio(FileSystem.SYSTEM, baseFileDir) }
118119

120+
// Monitoring
121+
122+
val crashMonitoring by lazy { CrashMonitoring(preferenceRepository) }
123+
119124
// Engine
120125

121126
private val taskEventMapper by lazy { TaskEventMapper(networkTypeFinder, json) }
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
package org.ooni.probe.shared.monitoring
2+
3+
import co.touchlab.kermit.LogWriter
4+
import co.touchlab.kermit.Severity
5+
import io.sentry.kotlin.multiplatform.Sentry
6+
import io.sentry.kotlin.multiplatform.SentryLevel
7+
import io.sentry.kotlin.multiplatform.protocol.Breadcrumb
8+
import kotlinx.coroutines.flow.collect
9+
import kotlinx.coroutines.flow.onEach
10+
import org.ooni.probe.data.models.SettingsKey
11+
import org.ooni.probe.data.repositories.PreferenceRepository
12+
13+
class CrashMonitoring(
14+
private val preferencesRepository: PreferenceRepository,
15+
) {
16+
private var isEnabled = false
17+
18+
suspend fun setup() {
19+
preferencesRepository.getValueByKey(SettingsKey.SEND_CRASH)
20+
.onEach { sendCrash ->
21+
if (sendCrash == true) {
22+
Sentry.init {
23+
it.dsn = SENTRY_DSN
24+
}
25+
isEnabled = true
26+
} else {
27+
isEnabled = false
28+
Sentry.close()
29+
}
30+
}
31+
.collect()
32+
}
33+
34+
val logWriter = object : LogWriter() {
35+
override fun isLoggable(
36+
tag: String,
37+
severity: Severity,
38+
): Boolean = isEnabled && severity != Severity.Verbose
39+
40+
override fun log(
41+
severity: Severity,
42+
message: String,
43+
tag: String,
44+
throwable: Throwable?,
45+
) {
46+
if (!isEnabled) return
47+
48+
if (severity == Severity.Error) {
49+
if (throwable != null) {
50+
addBreadcrumb(severity, message, tag)
51+
Sentry.captureException(throwable)
52+
} else {
53+
Sentry.captureMessage(message)
54+
}
55+
} else {
56+
addBreadcrumb(severity, message, tag)
57+
}
58+
}
59+
60+
private fun addBreadcrumb(
61+
severity: Severity,
62+
message: String,
63+
tag: String,
64+
) {
65+
Sentry.addBreadcrumb(
66+
Breadcrumb(
67+
level = when (severity) {
68+
Severity.Verbose,
69+
Severity.Debug,
70+
-> SentryLevel.DEBUG
71+
72+
Severity.Info -> SentryLevel.INFO
73+
Severity.Warn -> SentryLevel.WARNING
74+
Severity.Error -> SentryLevel.ERROR
75+
Severity.Assert -> SentryLevel.ERROR
76+
},
77+
type = when (severity) {
78+
Severity.Debug -> "debug"
79+
Severity.Error -> "error"
80+
else -> "default"
81+
},
82+
message = message,
83+
category = tag,
84+
),
85+
)
86+
}
87+
}
88+
89+
companion object {
90+
private const val SENTRY_DSN =
91+
"https://9dcd83d9519844188803aa817cdcd416@o155150.ingest.sentry.io/5619989"
92+
}
93+
}

gradle/libs.versions.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ okio = { module = "com.squareup.okio:okio", version = "3.9.0" }
5858
# WebView
5959
webview = { module = "io.github.kevinnzou:compose-webview-multiplatform", version = "1.9.20" }
6060

61+
# Crash Reporting
62+
sentry = { module = "io.sentry:sentry-kotlin-multiplatform", version = "0.9.0" }
63+
6164
# Testing
6265
android-test-core = { module = "androidx.test:core", version = "1.6.1" }
6366

@@ -79,6 +82,7 @@ tooling = [
7982
"okio",
8083
"webview",
8184
"markdown",
85+
"sentry",
8286
]
8387
android = [
8488
"android-oonimkall",

iosApp/Podfile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ target 'OONIProbe' do
1010

1111
pod 'sqlite3', '~> 3.42.0'
1212

13+
pod("Sentry") {
14+
version = "~> 8.25"
15+
linkOnly = true
16+
extraOpts += listOf("-compiler-option", "-fmodules")
17+
}
18+
1319
pod "libcrypto", :podspec => "#{ooni_pods_location}/libcrypto.podspec"
1420
pod "libevent", :podspec => "#{ooni_pods_location}/libevent.podspec"
1521
pod "libssl", :podspec => "#{ooni_pods_location}/libssl.podspec"

iosApp/Podfile.lock

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ PODS:
66
- libtor (2024.05.22-093305)
77
- libz (2024.05.22-093305)
88
- oonimkall (2024.05.22-093305)
9+
- Sentry (8.36.0):
10+
- Sentry/Core (= 8.36.0)
11+
- Sentry/Core (8.36.0)
912
- sqlite3 (3.42.0):
1013
- sqlite3/common (= 3.42.0)
1114
- sqlite3/common (3.42.0)
@@ -18,10 +21,12 @@ DEPENDENCIES:
1821
- libtor (from `https://github.com/ooni/probe-cli/releases/download/v3.22.0/libtor.podspec`)
1922
- libz (from `https://github.com/ooni/probe-cli/releases/download/v3.22.0/libz.podspec`)
2023
- oonimkall (from `https://github.com/ooni/probe-cli/releases/download/v3.22.0/oonimkall.podspec`)
24+
- Sentry
2125
- sqlite3 (~> 3.42.0)
2226

2327
SPEC REPOS:
2428
trunk:
29+
- Sentry
2530
- sqlite3
2631

2732
EXTERNAL SOURCES:
@@ -48,8 +53,9 @@ SPEC CHECKSUMS:
4853
libtor: c72b23da6a5d2e16173149784f11cf66156c35be
4954
libz: 83658eb2a0db785623ffdf9ce13407e6b8b5c8f9
5055
oonimkall: 9768ce9dad18265d45d2ea972c84fb0bd5237cc3
56+
Sentry: f8374b5415bc38dfb5645941b3ae31230fbeae57
5157
sqlite3: f163dbbb7aa3339ad8fc622782c2d9d7b72f7e9c
5258

53-
PODFILE CHECKSUM: c5dc5bf29da7489163ae2c4d6b438c4541281e5d
59+
PODFILE CHECKSUM: c56cd1cda3f9819515b4e5a812551173754d1cae
5460

5561
COCOAPODS: 1.15.2

0 commit comments

Comments
 (0)