xref: /aosp_15_r20/external/leakcanary2/docs/uploading.md (revision d9e8da70d8c9df9a41d7848ae506fb3115cae6e6)
1*d9e8da70SAndroid Build Coastguard Worker# Uploading analysis results
2*d9e8da70SAndroid Build Coastguard Worker
3*d9e8da70SAndroid Build Coastguard WorkerYou can add an `EventListener` to upload the analysis result to a server of your choosing:
4*d9e8da70SAndroid Build Coastguard Worker
5*d9e8da70SAndroid Build Coastguard Worker```kotlin
6*d9e8da70SAndroid Build Coastguard Workerclass DebugExampleApplication : ExampleApplication() {
7*d9e8da70SAndroid Build Coastguard Worker
8*d9e8da70SAndroid Build Coastguard Worker  override fun onCreate() {
9*d9e8da70SAndroid Build Coastguard Worker    super.onCreate()
10*d9e8da70SAndroid Build Coastguard Worker    val analysisUploadListener = EventListener { event ->
11*d9e8da70SAndroid Build Coastguard Worker      if (event is HeapAnalysisSucceeded) {
12*d9e8da70SAndroid Build Coastguard Worker        val heapAnalysis = event.heapAnalysis
13*d9e8da70SAndroid Build Coastguard Worker        TODO("Upload heap analysis to server")
14*d9e8da70SAndroid Build Coastguard Worker      }
15*d9e8da70SAndroid Build Coastguard Worker    }
16*d9e8da70SAndroid Build Coastguard Worker
17*d9e8da70SAndroid Build Coastguard Worker    LeakCanary.config = LeakCanary.config.run {
18*d9e8da70SAndroid Build Coastguard Worker      copy(eventListeners = eventListeners + analysisUploadListener)
19*d9e8da70SAndroid Build Coastguard Worker    }
20*d9e8da70SAndroid Build Coastguard Worker  }
21*d9e8da70SAndroid Build Coastguard Worker}
22*d9e8da70SAndroid Build Coastguard Worker```
23*d9e8da70SAndroid Build Coastguard Worker
24*d9e8da70SAndroid Build Coastguard Worker## Uploading to Bugsnag
25*d9e8da70SAndroid Build Coastguard Worker
26*d9e8da70SAndroid Build Coastguard WorkerA leak trace has a lot in common with a stack trace, so if you lack the engineering resources to
27*d9e8da70SAndroid Build Coastguard Workerbuild a backend for LeakCanary, you can instead upload leak traces to a crash reporting backend.
28*d9e8da70SAndroid Build Coastguard WorkerThe client needs to support grouping via custom client-side hashing as well as custom metadata with
29*d9e8da70SAndroid Build Coastguard Workersupport for newlines.
30*d9e8da70SAndroid Build Coastguard Worker
31*d9e8da70SAndroid Build Coastguard Worker!!! info
32*d9e8da70SAndroid Build Coastguard Worker    As of this writing, the only known library suitable for uploading leaks is the Bugsnag client.
33*d9e8da70SAndroid Build Coastguard Worker    If you managed to make it work with another library, please [file an issue](https://github.com/square/leakcanary/issues/new/choose).
34*d9e8da70SAndroid Build Coastguard Worker
35*d9e8da70SAndroid Build Coastguard WorkerCreate a [Bugsnag account](https://app.bugsnag.com/user/new/), create a new project for leak
36*d9e8da70SAndroid Build Coastguard Workerreporting and grab an **API key**. Make sure the app has the `android.permission.INTERNET`
37*d9e8da70SAndroid Build Coastguard Workerpermission then add the [latest version](https://docs.bugsnag.com/platforms/android/) of the
38*d9e8da70SAndroid Build Coastguard WorkerBugsnag Android client library to `build.gradle`:
39*d9e8da70SAndroid Build Coastguard Worker
40*d9e8da70SAndroid Build Coastguard Worker```groovy
41*d9e8da70SAndroid Build Coastguard Workerdependencies {
42*d9e8da70SAndroid Build Coastguard Worker  // debugImplementation because LeakCanary should only run in debug builds.
43*d9e8da70SAndroid Build Coastguard Worker  debugImplementation 'com.squareup.leakcanary:leakcanary-android:{{ leak_canary.release }}'
44*d9e8da70SAndroid Build Coastguard Worker  debugImplementation "com.bugsnag:bugsnag-android:$bugsnagVersion"
45*d9e8da70SAndroid Build Coastguard Worker}
46*d9e8da70SAndroid Build Coastguard Worker```
47*d9e8da70SAndroid Build Coastguard Worker
48*d9e8da70SAndroid Build Coastguard Worker!!! info
49*d9e8da70SAndroid Build Coastguard Worker    If you're only using Bugsnag for uploading leaks, then you do not need to set up the Bugsnag
50*d9e8da70SAndroid Build Coastguard Worker    Gradle plugin or to configure the API key in your app manifest.
51*d9e8da70SAndroid Build Coastguard Worker
52*d9e8da70SAndroid Build Coastguard WorkerCreate a new `BugsnagLeakUploader`:
53*d9e8da70SAndroid Build Coastguard Worker
54*d9e8da70SAndroid Build Coastguard Worker--8<-- "docs/snippets/bugsnag-uploader.md"
55*d9e8da70SAndroid Build Coastguard Worker
56*d9e8da70SAndroid Build Coastguard WorkerThen add an `EventListener` to upload the analysis result to Bugsnag:
57*d9e8da70SAndroid Build Coastguard Worker
58*d9e8da70SAndroid Build Coastguard Worker```kotlin
59*d9e8da70SAndroid Build Coastguard Workerclass DebugExampleApplication : ExampleApplication() {
60*d9e8da70SAndroid Build Coastguard Worker
61*d9e8da70SAndroid Build Coastguard Worker  override fun onCreate() {
62*d9e8da70SAndroid Build Coastguard Worker    super.onCreate()
63*d9e8da70SAndroid Build Coastguard Worker    LeakCanary.config = LeakCanary.config.copy(
64*d9e8da70SAndroid Build Coastguard Worker        onHeapAnalyzedListener = BugsnagLeakUploader(applicationContext = this)
65*d9e8da70SAndroid Build Coastguard Worker    )
66*d9e8da70SAndroid Build Coastguard Worker  }
67*d9e8da70SAndroid Build Coastguard Worker}
68*d9e8da70SAndroid Build Coastguard Worker```
69*d9e8da70SAndroid Build Coastguard Worker
70*d9e8da70SAndroid Build Coastguard WorkerYou should start seeing leaks reported into Bugsnag, grouped by their leak signature:
71*d9e8da70SAndroid Build Coastguard Worker
72*d9e8da70SAndroid Build Coastguard Worker![list](images/bugsnag-list.png)
73*d9e8da70SAndroid Build Coastguard Worker
74*d9e8da70SAndroid Build Coastguard WorkerThe `LEAK` tab contains the leak trace:
75*d9e8da70SAndroid Build Coastguard Worker
76*d9e8da70SAndroid Build Coastguard Worker![leak](images/bugsnag-leak.png)
77