Why I Use Crashlytics - Part 2
Introduction
I often get asked what libraries I use when writing new greenfield Android apps or what libraries I introduce when I start working for a new client when helping them with an existing application they already have in production. Of course I always rely on a few key libraries such as Dagger, Otto/RxJava, Retrofit and a few others but one I absolutely always use is Crashlytics.
Crashlytics is a free service offered by Twitter that collects your crashes and various other bits of information. It's very easy to setup and install and it instantly starts providing value as soon as you install it - yes, even in development. It's completely free, it has unlimited apps, unlimited users, unlimited crashes, unlimited keys, etc. - it's all free. I’m not joking when I say it's the first thing I install. Without crash reporting I have no idea what's happening to my app in the wild (production).
Why Crash Reporting is Important
When your app crashes in production on a user's device you need to know. The reason is simple - something happened that you did not expect. Perhaps you used an API that was not supported for your release (such as using Renderscripts InstrinsicBlur on API level 15 when that API was not released until 17). When this happens over and over, your users start to lose faith in your application and then the bad reviews start rolling in.
When you’re monitoring your crashes you’re able to assess the risk level that a particular crash is causing. For example, let’s assume that you release version 2.0 of your application. Upon doing so you introduced a bug on a particular screen. During development and testing you never ran into this issue, but as soon as you released the update to your existing users you start getting inundated with crash reports. With a crash monitoring tool you can then observe that the crash is occurring on a particular screen because you’re given the stack trace of the crash. For some reason the crash is occurring on the getActivity()
call of a Fragment - a NullPointerException
to be exact. Upon further investigation you realize/remember that all getActivity()
calls in Fragments can return null (and in production and at scale they will). You then implement the null check, and ship a hot fix version to address the issue at hand. This is a real world case I have witnessed many times for various clients. We would have never caught it without a crash reporting tool.
Not All Crash Reporting Tools are Created Equally
Prior to Crashlytics I installed various other crash reporting tools such as Bugsense, Crittercism, ACRA, HockeyApp and some others. The problems I encountered with these services were numerous and were different for each tool I used. Some of the issues I encountered included:
- The tool was hosted and the fees were outrageous
- The tool was free, but did not scale unless I built out a backend API to support it
- The integration was rather cumbersome
- Account management was painful if not non-existent
- Sharing bug reports was difficult
- IDE integration was non-existent
- If I used Proguard my stack traces were obfuscated so I could not fix the issue.
I usually ended up working with either ACRA or Bugsense prior to Crashlytics. ACRA for smaller apps that did not have much of a budget or very low user base and Bugsense for larger clients. I attempted to use HockeyApp a couple of times but my clients never got around to setting up accounts and found that they liked Bugsense more or preferred the cost of ACRA - FREE.
ACRA worked well, but one thing I noticed was that I never checked in on the Google Sheet where the crashes were sent. Unfortunately due to the way the crashes were stored in Google Sheets I found that they were not optimal for reading. The process of checking for new crashes was very poll based and I found this unfortunate. Sure, there were tools that did help in solving some of these problems but the solution was far from perfect, elegant or quick. I also did not have the statistics that I wanted, such as percentage of Android 2.x users affected vs. Android 4.x users, etc. This kind of data really helps identify the impact of the crash. If your user base is 95% Android 4.x and the crash is occurring on Android 2.x then your impact is rather low. When flipped in the other direction though, you have a very large set of users whom the crash is affecting and at that point different decisions need to be made (hot fix, etc.). The key point here is that ACRA is not a fully baked solution in the way other advanced crash reporting tools are.
Bugsense and Crittercism (and other services) solved a lot of the issues I had with ACRA, but I found that the price point was a huge turn off for almost all of my clients. One of the great features of these services was a pushed based system that would notify you of when a new crash occurred. This could be via email, etc. Not having to log in and check manually was a huge time savings. My clients have either very large Android Apps (millions upon millions of installs/users) or very small (new startup, etc.). The price point bodes problematic for both. On the lower end of the spectrum the new startup is trying to save money at every area possible and they don’t want to pay for crash reporting. Every penny affects their runway. Therefore, we usually ended up with a sub-par solution like ACRA. On the upper end of the spectrum we had a different problem - application scale. These clients are at such a scale that the pricing tier they fall into simply says: "call us for a quote." This usually equated to tens of thousands of dollars per month in licensing fees. While these larger clients could pay for it (and some did) they really didn’t enjoy paying that much for a crash reporting solution.
When Crashlytics was announced for Android last year it seemed too good to be true, but it wasn't. Seeing that Crashlytics is a free solution that can handle large scale applications and provides the metrics that I need for both large and small clients - it was a no brainer. User management was super easy with Crashlytics too. Being that I’m a consultant I am able to be part of many Crashlytics 'Organizations' at once with one login. At this time I have one login and I’m part of seven different teams with different apps in different verticals. Crashlytics provides a push based mechanism (in the IDE and email) to notify me of new crashes as they occur.
Luckily, I was invited to participate in the Android private beta for Maven users and Android Studio users last year. I jumped at the opportunity and brought my client, MyFitnessPal (#1 Free Health and Fitness app in Google Play) along for the ride. At MyFitnessPal we now use Crashlytics as our primary tool for managing crashes and assessing risk during post release of a new version.
Working With Crashlytics in Production
Upon working with Crashlytics we were given access to their private portal (now public) for Android developers. This gave us access to the area where we were given instructions on how to install the plugin. Normally these types of instructions are provided via webpage and a few steps to follow. Not the case with Crashlytics. They provided a full powered walk through on their site at www.crashlytics.com/downloads/plugins. You can choose your IDE or your build tool as shown in the figure below:
The Crashlytics guided installation tour
I either choose Android Studio or IntelliJ as these are my preferred IDE’s. Depending upon what client I’m working I may be working with a different IDE. It's important to note that if you do not use one of these IDE’s you're not out of luck, you can choose the build tool of your choice as shown below:
You can also choose a build tool to help with set up.
The nice thing about choosing an IDE is that you get to install a plugin for that IDE and Crashlytics is nice enough to guide you through the process per IDE. Here’s a sample screenshot from the Android Studio walk through.
The Android Studio plugin installation walkthrough
Once the plugin is installed you can view the plugin by opening the toolbar in Android Studio by ensuring that View → Toolbar is selected (for other IDE’s please see the documentation). Once this is open you will see the Crashlytics landing page as shown below:
The Crashlytics plugin landing screen.
Select the power button and the Plugin will detect which application you currently have open and at that point you will be walked through the setup process. One very important thing to note is that since I’m a consultant it’s very important for me to be part of multiple teams (known as Organizations in Crashlytics). While setting up a project I’m asked what organization I want this new application I’m setting up to be part of. As you can see from the list below I’m part of a few organizations. I can select which one I’d like this app to be listed in and then I’m ready to go.
The organization selector in the Crashlytics Plugin.
After you’ve selected your organization Crashlytics will inform you that it's going to update a few files for you. This is great! I get to preview the changes and Crashlytics implements the changes for me. Awesome! Here’s what it looks like when setting up an application:
The Crashlytics Plugin informs you that it will be making changes to your application code for you.
One important thing to notice here is that the Crashlytics plugin was able to detect that I’m using Gradle as my build tool for this project and is implementing the correct Gradle syntax for me! I did not select Gradle from the choices when setting up the IDE, I simply chose 'Android Studio' and Crashlytics did the rest.
Once you hit the next button you’ll be informed that you need to launch your app so that Crashlytics can detect that it’s running.
The Crashlytics Plugin waiting to hear from your app.
Once the app is built and is deployed the Crashlytics Plugin will recognize the app and will display the crash interface to you as shown below.
The Crashlytics Plugin interface analyzing the current app with installed.
Once Crashlytics recognizes your application they even give you instructions on how to force a crash if you’d like. Once crashes start showing up you can see them via the plugin as shown below.
As crash shown in Crashlytics plugin.
Upon clicking on the issue (the crash on MainActivity.java as shown in the figure above) you’re taken to the web based issue detail screen where you get a plethora of information about the issue that caused the crash. On this screen alone the following data is provided to you:
A screenshot of a Crashlytics Issue page on the Crashlytics site.
1. |
Application and Package name |
The application and package name of the app that has this issue. |
2. |
Error Location |
Where in the crash occurred in the source code. |
3. |
Total Crash Count |
The total number of crashes reported for this issue. |
4. |
Total User Count |
The total number of unique users that have experienced this issue. |
5. |
Open / Close Switch |
Toggles the issue as open or closed for this particular version of the app. If another crash for the same version of the app comes in after you close the issue, the issue will remain closed. However if you release a new version of the app and the crash occurs a new issue will be opened. |
6. |
Crash Graph |
This graph displays the number of crashes on each given day over a period of time. |
7. |
Share Options |
Options to tweet, email/copy the short issue link to send to another person for review. |
8. |
Android Device Breakdown Charts |
These charts show the various devices affected by this issue. |
9. |
Android Operating System Charts |
These charts show the various Android Operating systems that are experiencing this crash. |
10. |
% Rooted |
Displays the percentage of rooted devices that are experiencing the crash. |
11. |
Free Space |
The average free space on a device that has had this crash occur. |
12. |
Free RAM |
The average amount of free RAM on a device that has had this crash occur. |
13. |
App In Focus |
The percentage of times that the app was in focus when the crash occurred. |
14. |
Proximity On |
The percentage of the devices that had their proximity sensors on when this crash occurred. |
15. |
Expandable Crash Stack Trace |
A expandable stack trace explorer for the crash. You can inspect the various aspects of the code that was executing that caused the crash in this area of the issue report. |
16 |
Notes Field (not shown) |
At the bottom there is a notes field where you and your teammates can add various notes to the issue. |
Using this data you can determine if this is a critical crash and if it should be fixed. I tend to particularly review the crash count, affected user count, device and OS breakdown initially. Crashlytics does provide each issue with an automatic severity level assignment that will help you determine what to do.
So what can you do with all this data from Crashlytics? In Part 2 of this series, we’ll do a deep dive on how this data helps you fix the most critical crashes with minimal effort and create happy users/customers for your business. We’ll be releasing Part 2 sometime next week -- stay tuned!
In the meantime, learn more about Crashlytics for Android.