Skip to content
This repository was archived by the owner on Oct 15, 2024. It is now read-only.

Commit 8e3b442

Browse files
committed
feat(app): add implementations for SentryLeakUploader
1 parent acdad21 commit 8e3b442

File tree

2 files changed

+75
-0
lines changed

2 files changed

+75
-0
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package app.passwordstore.util.leaks
2+
3+
import leakcanary.EventListener
4+
5+
object SentryLeakUploader : EventListener {
6+
7+
override fun onEvent(event: EventListener.Event) {}
8+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package app.passwordstore.util.leaks
2+
3+
import io.sentry.Sentry
4+
import io.sentry.SentryEvent
5+
import leakcanary.EventListener
6+
import leakcanary.EventListener.Event
7+
import shark.HeapAnalysisSuccess
8+
import shark.Leak
9+
import shark.LeakTrace
10+
import shark.LibraryLeak
11+
12+
object SentryLeakUploader : EventListener {
13+
14+
override fun onEvent(event: Event) {
15+
when (event) {
16+
is Event.HeapAnalysisDone<*> -> {
17+
if (event.heapAnalysis !is HeapAnalysisSuccess) return
18+
val heapAnalysis = event.heapAnalysis as HeapAnalysisSuccess
19+
val allLeakTraces =
20+
heapAnalysis.allLeaks.toList().flatMap { leak ->
21+
leak.leakTraces.map { leakTrace -> leak to leakTrace }
22+
}
23+
24+
allLeakTraces.forEach { (leak, leakTrace) ->
25+
val exception = FakeReportingException(leak.shortDescription)
26+
val sentryEvent =
27+
SentryEvent(exception).apply {
28+
val leakContexts = mutableMapOf<String, Any>()
29+
addHeapAnalysis(heapAnalysis, leakContexts)
30+
addLeak(leak, leakContexts)
31+
addLeakTrace(leakTrace, leakContexts)
32+
contexts["Leak"] = leakContexts
33+
// grouping leaks
34+
fingerprints = listOf(leak.signature)
35+
}
36+
Sentry.captureEvent(sentryEvent)
37+
}
38+
}
39+
else -> {}
40+
}
41+
}
42+
43+
private fun addHeapAnalysis(
44+
heapAnalysis: HeapAnalysisSuccess,
45+
leakContexts: MutableMap<String, Any>
46+
) {
47+
leakContexts["heapDumpPath"] = heapAnalysis.heapDumpFile.absolutePath
48+
heapAnalysis.metadata.forEach { (key, value) -> leakContexts[key] = value }
49+
leakContexts["analysisDurationMs"] = heapAnalysis.analysisDurationMillis
50+
}
51+
52+
private fun addLeak(leak: Leak, leakContexts: MutableMap<String, Any>) {
53+
leakContexts["libraryLeak"] = leak is LibraryLeak
54+
if (leak is LibraryLeak) {
55+
leakContexts["libraryLeakPattern"] = leak.pattern.toString()
56+
leakContexts["libraryLeakDescription"] = leak.description
57+
}
58+
}
59+
60+
private fun addLeakTrace(leakTrace: LeakTrace, leakContexts: MutableMap<String, Any>) {
61+
leakTrace.retainedHeapByteSize?.let { leakContexts["retainedHeapByteSize"] = it }
62+
leakContexts["signature"] = leakTrace.signature
63+
leakContexts["leakTrace"] = leakTrace.toString()
64+
}
65+
66+
class FakeReportingException(message: String) : RuntimeException(message)
67+
}

0 commit comments

Comments
 (0)