Skip to content

Instantly share code, notes, and snippets.

@marandaneto
Created May 23, 2020 09:38
Show Gist options
  • Save marandaneto/a6e6286212dabc2ea15cac672d425f7f to your computer and use it in GitHub Desktop.
Save marandaneto/a6e6286212dabc2ea15cac672d425f7f to your computer and use it in GitHub Desktop.
import io.sentry.core.Sentry
import io.sentry.core.SentryEvent
import leakcanary.DefaultOnHeapAnalyzedListener
import leakcanary.OnHeapAnalyzedListener
import shark.HeapAnalysis
import shark.HeapAnalysisFailure
import shark.HeapAnalysisSuccess
import shark.Leak
import shark.LeakTrace
import shark.LibraryLeak
class SentryLeakUploader : OnHeapAnalyzedListener {
private val defaultLeakListener = DefaultOnHeapAnalyzedListener.create()
override fun onHeapAnalyzed(heapAnalysis: HeapAnalysis) {
// Delegate to default behavior (notification and saving result)
defaultLeakListener.onHeapAnalyzed(heapAnalysis)
when (heapAnalysis) {
is HeapAnalysisSuccess -> {
val allLeakTraces = heapAnalysis
.allLeaks
.toList()
.flatMap { leak ->
leak.leakTraces.map { leakTrace -> leak to leakTrace }
}
allLeakTraces.forEach { (leak, leakTrace) ->
val exception = FakeReportingException(leak.shortDescription)
val event = SentryEvent(exception).apply {
val leakExtras = mutableMapOf<String, Any>()
addHeapAnalysis(heapAnalysis, leakExtras)
addLeak(leak, leakExtras)
addLeakTrace(leakTrace, leakExtras)
setExtra("Leak", leakExtras)
// grouping leaks
fingerprints = listOf(leak.signature)
}
Sentry.captureEvent(event)
}
}
is HeapAnalysisFailure -> {
// Please file any reported failure to
// https://github.com/square/leakcanary/issues
Sentry.captureException(heapAnalysis.exception)
}
}
}
private fun addHeapAnalysis(heapAnalysis: HeapAnalysisSuccess, leakExtras: MutableMap<String, Any>) {
leakExtras["heapDumpPath"] = heapAnalysis.heapDumpFile.absolutePath
heapAnalysis.metadata.forEach { (key, value) ->
leakExtras[key] = value
}
leakExtras["analysisDurationMs"] = heapAnalysis.analysisDurationMillis
}
private fun addLeak(leak: Leak, leakExtras: MutableMap<String, Any>) {
leakExtras["libraryLeak"] = leak is LibraryLeak
if (leak is LibraryLeak) {
leakExtras["libraryLeakPattern"] = leak.pattern.toString()
leakExtras["libraryLeakDescription"] = leak.description
}
}
private fun addLeakTrace(leakTrace: LeakTrace, leakExtras: MutableMap<String, Any>) {
leakTrace.retainedHeapByteSize?.let {
leakExtras["retainedHeapByteSize"] = it
}
leakExtras["signature"] = leakTrace.signature
leakExtras["leakTrace"] = leakTrace.toString()
}
class FakeReportingException(message: String) : RuntimeException(message)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment