When logging stack traces for unhandled exceptions in Java or Android (e.g. via ACRA), you usually get the stack trace as a plain long string.
Now all services that offer crash reporting and analysis (e.g. Google Play Developer Console, Crashlytics) group those stack traces into unique buckets. This is obviously helpful -- otherwise, you could have tens of thousands of crash reports in your list, but only a dozen of them may be unique.
Example:
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:200)
at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274)
at java.util.concurrent.FutureTask.setException(FutureTask.java:125)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
at java.lang.Thread.run(Thread.java:1027)
Caused by: java.lang.ArrayIndexOutOfBoundsException
at com.my.package.MyClass.i(SourceFile:1059)
...
The stack trace above may appear in multiple variants, e.g. the platform classes like AsyncTask
may appear with varying line numbers due to different platform versions.
What's the best technique to get a unique identifier for every crash report?
What's clear is that with every new application version that you publish, crash reports should be handled separatedly, because the compiled source is different. In ACRA, you can consider using the field APP_VERSION_CODE
.
But otherwise, how do you identify reports with unique causes? By taking the first line and searching for the first occurrence of a custom (non-platform) class and looking up the file and line number?
JavaCrashId.from(exception)
plus the app version code seem to be working for me as a crash fingerprint. – Borstal