Skip to content

Commit 2682435

Browse files
Merge pull request #2026 from Infomaniak/realm-breadcrumbs
Calm down Realm breadcrumbs
2 parents 6b097a1 + f56e69c commit 2682435

File tree

2 files changed

+57
-10
lines changed

2 files changed

+57
-10
lines changed

app/src/main/java/com/infomaniak/mail/MainApplication.kt

+7
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,13 @@ open class MainApplication : Application(), ImageLoaderFactory, DefaultLifecycle
170170

171171
private fun configureSentry() {
172172
SentryAndroid.init(this) { options: SentryAndroidOptions ->
173+
174+
/**
175+
* The default value is 100.
176+
* But Realm breadcrumbs are spamming a lot, so we increase this limit for now, to see if it's enough or not.
177+
*/
178+
options.maxBreadcrumbs = 200
179+
173180
// Register the callback as an option
174181
options.beforeSend = SentryOptions.BeforeSendCallback { event: SentryEvent, _: Any? ->
175182
val isNetworkException = event.exceptions?.any { it.type == "ApiController\$NetworkException" } ?: false

app/src/main/java/com/infomaniak/mail/utils/SentryRealmLogger.kt

+50-10
Original file line numberDiff line numberDiff line change
@@ -22,24 +22,64 @@ import io.realm.kotlin.log.RealmLogger
2222
import io.sentry.Breadcrumb
2323
import io.sentry.Sentry
2424
import io.sentry.SentryLevel
25+
import kotlinx.coroutines.CoroutineScope
26+
import kotlinx.coroutines.Dispatchers
27+
import kotlinx.coroutines.launch
28+
import kotlinx.coroutines.sync.Mutex
29+
import kotlinx.coroutines.sync.withLock
2530

2631
class SentryRealmLogger : RealmLogger {
2732

28-
override val level: LogLevel = LogLevel.DEBUG
33+
private val mutex = Mutex()
34+
private val messagesMap = mutableMapOf<Long, MutableList<String>>()
2935

30-
override val tag: String = "Realm"
36+
override val level = LogLevel.DEBUG
37+
override val tag = "Realm"
3138

3239
override fun log(level: LogLevel, throwable: Throwable?, message: String?, vararg args: Any?) {
40+
3341
val throwableMessage = throwable?.message
34-
val breadcrumb = if (throwableMessage == null) {
35-
Breadcrumb().apply {
36-
this.level = SentryLevel.INFO
37-
this.category = tag
38-
this.message = "($tag): $message"
42+
if (throwableMessage != null) {
43+
val breadcrumb = Breadcrumb.error(throwableMessage).apply { category = "exception" }
44+
Sentry.addBreadcrumb(breadcrumb)
45+
return
46+
}
47+
48+
CoroutineScope(Dispatchers.IO).launch {
49+
mutex.withLock {
50+
val now = System.currentTimeMillis() / MAX_DELAY
51+
52+
message?.let {
53+
if (messagesMap[now] == null) {
54+
messagesMap[now] = mutableListOf(it)
55+
} else {
56+
messagesMap[now]?.add(it)
57+
}
58+
}
59+
60+
var shouldContinue = true
61+
while (shouldContinue) {
62+
val key = messagesMap.keys.firstOrNull()
63+
val values = messagesMap[key]
64+
if (key != null && (key < now || values!!.count() > MAX_ZIP)) {
65+
val breadcrumb = Breadcrumb().apply {
66+
this.level = SentryLevel.INFO
67+
this.category = tag
68+
this.message = values?.joinToString(separator = "\n") { it }
69+
}
70+
Sentry.addBreadcrumb(breadcrumb)
71+
messagesMap.remove(key)
72+
73+
} else {
74+
shouldContinue = false
75+
}
76+
}
3977
}
40-
} else {
41-
Breadcrumb.error(throwableMessage).apply { category = "exception" }
4278
}
43-
Sentry.addBreadcrumb(breadcrumb)
79+
}
80+
81+
companion object {
82+
private const val MAX_DELAY = 100
83+
private const val MAX_ZIP = 100
4484
}
4585
}

0 commit comments

Comments
 (0)