Crashes / Errors

Follow
Availability

The Crashes/Errors feature is available in both Countly Lite and Countly Enterprise.

The Crashes feature enables you to monitor the stability of your Android and iOS applications with a real-time view of fatal and non-fatal crashes that may have occurred, and which users may have been impacted by these issues. The feature is known as Crashes for Android and iOS applications, and Errors for web applications. 

Benefits of Crashes

The Crashes feature allows you to quickly identify crashes by OS, device, carrier, and other factors, so that developers can remedy issues more quickly, while also updating and keeping track of resolution status. The feature also allows you to download reports with details that help you identify and resolve issues including, but not limited to, application version, platform, screen resolution, RAM, disk, battery level, and operating system.​​ Through its real-time information capture, the Crashes feature ensures swift resolution, reducing customer dissatisfaction and app uninstalls while helping you enhance customer experience.

Getting Started

To start collecting Crashes (and Errors) data, you need to enable the Crashes feature through the applicable SDK.

Setting up Crashes on iOS SDK

The Countly SDK for iOS allows you to set up and collect data on crashes on any iOS device. To enable automatic crash data collection, you will need to specify CLYCrashReporting in features array on the CountlyConfig object before starting Countly. Once this is done, the Countly iOS SDK will generate a crash report, i.e., collect crashes data, if your application crashes due to an exception and send it to the Countly Server for further inspection. If crash data cannot be delivered to the server for any reason, e.g., no internet connection or unavailable server at the time of the crash, the Countly iOS SDK will store the information locally in order to make another attempt at a later time.

For more details, including manually handled exceptions, refer to the Countly SDK for iOS document.

Using iOS SDK with Another Crash SDK

In iOS, there can be only one uncaught exception handler. Even though it is possible to save the previous handler and pass the uncaught exception to the previous handler as well, it is not safe to assume that it will work in all cases. As we can't know how other SDKs are implemented or whether iOS will provide enough time for all the handlers to do their work before terminating the app, we advise using Countly as the only crash handler.

Setting up Crashes on Android SDK

The Countly SDK for Android allows you to set up and collect data on crashes on any Android device. To enable automatic crash data collection, call the following function on the config object. After init, this will enable crash data collection, which will automatically catch uncaught Java exceptions. This data will be sent to Countly once the app is launched again and the SDK is initiated.

config.enableCrashReporting();

For more details, refer to the Countly SDK for Android document.

Using Android SDK with Another Crash SDK

It should be fine to use Countly together with another crash SDK. If you would like to track caught exception, you would just pass them to both SDKs. When catching uncaught exceptions with both, there are some uncertainties. Although in Android there can be only one uncaught exception handler, you can save the previous handler and, when receiving an uncaught exception, pass it to the saved one also. We can't be certain how other SDKs are implemented or if the OS would provide enough time to propagate the exception through all handlers. Therefore, if you want to use Countly with another crash SDK, we advise initializing Countly as the last one.

Crashes Overview

Information Collected

Enabling the Crashes feature will send the below information to the Countly server.

Crash Related Information

  • Operating system (e.g., Android)
  • Operating system version (e.g., 5.1)
  • Manufacturer (e.g., Samsung)
  • Device (e.g., Galaxy S6)
  • Resolution
  • Application version
  • CPU (e.g., armv7)
  • OpenGL version (e.g., 2.0)
  • Occurrences
  • Affected Visitors

State of Device

  • Free RAM size (e.g., 2108, in MB)
  • Total RAM size
  • Free disk size (e.g., 3400, in MB)
  • Total disk size
  • Current battery level (e.g., 30)
  • Orientation (landscape or portrait)

Boolean Data (yes/no)

  • Is the device rooted?
  • Is the device online?
  • Is the device muted?
  • Was the app running in the background?

Detailed Error Information

  • Full stack trace of error
  • Fatal or non-fatal
  • Additional logs logged by SDK
  • Running time since app start (seconds)

Custom key/values Provided by Developers

  • Graphiclib (e.g., 2.1)
  • Paymentlib (e.g., 1.0)

Metadata

In addition to crash-related data, Crashes also captures device info by default. You can add custom logs only to be delivered in case of a crash, independent of events. Moreover, you can set custom segments to specify which external libraries and frameworks are included in your project and their versions.

Exceptions

System signals (for iOS) and uncaught exceptions (for both iOS and Android) are automatically handled by the Countly SDKs. You can also submit exceptions handled by yourself.

Out of Memory (OOM) Crashes

As terminations due to low memory cannot be considered regular exceptions in iOS or Android, it is not possible to handle them correctly. We're working on a solution for ANR in Android.

Tip!

Countly can automatically group similar crashes so you do not have to.

Types of Crashes

Crashes are categorized on the basis of their status. Types of Crashes include:

  • All: All crash types
  • Fatal: A crash that causes the application to stop and quit.
  • Nonfatal: A crash that doesn't stop the application but allows it to run after a crash is encountered.
  • Hidden: Crashes that have been hidden from view, so as to not clutter how crash data is presented in Countly.
  • Viewed: Crashes that have been viewed and may be being resolved.
  • Reoccured: Crashes that have occurred before.
  • New: New crashes that you haven't viewed as yet
  • Resolved: Crashes whose underlying issue has been resolved.
  • Unresolved: Crashes that are not marked as Resolved are unresolved crashes.
  • Resolving: Crashes that are currently in the process of being resolved.

Using Crashes

The Crashes feature is broken down into the following Views:

  • Crash Groups: In Countly, go to Main Menu > Crashes > Overview; this is the default View.
  • Crash Statistics: Once on the Crash Groups View in Overview, click on the tab titled Crash Statistics.
  • Crash Details: Once on the Crash Groups View in Overview, click on any crash group on the list to open Crash Details.
  • Manage Symbols: In Countly, go to Main Menu > Crashes > Manage Symbols

Crash Groups

Crash Groups is the default View in Crashes > Overview. Crash Groups can be defined as the set of crashes grouped together on the basis of shared criteria.

crashes1.png

Determining Filters

To start, you need to first determine the criteria of the crash you want to delve into. You can apply a filter to crash groups on the Overview page, and these filters are grouped as Main filters (like fatality, visibility, reoccured etc.) and Detail filters (like device, app version, etc.). Here is an example that you can apply to your crash groups.

Screen_Shot_2022-02-16_at_21.22.08.png

Crash Groups Data Table

The data table is populated with the following details:

  • Crash Groups: For each item in this column, you will see basic crash details including the name of the crash, the developer/engineer who may be working on its resolution, and tags indicating the fatality and resolution status of the crash.
  • Platform: Details of the platform on which the device in question was operating when the crash occurred.
  • Occurrences: Number of times this crash has occurred.
  • Last Occurrences: Number of days since the last time that this crash occurred.
  • Affected Users: Number of users who faced this crash.
  • Latest App Version: Version of your app installed and on which the crash occurred.

The data table also enables you to undertake the below actions:

  • Search: You can search for specific crash groups or information by using the search bar located at the top right of the data table.
  • Download a Report: Download a report for the selected filters by clicking on the Downward Arrow next to the search bar.
  • See More/Fewer Details: You can use the column menu customization button next to the download button and check/uncheck any column heads to see more/less data or re-order columns.
  • Select specific crash groups by selecting the box to the left of each group, and then mark it as Seen, Resolved, Resolving, Unresolved, or Hidden, or Delete these by clicking on the bottom bar on the bottom of the page, which will appear when you select at least one crash group.

Crash Statistics

To go to the Crash Statistics View, click on the Crash Statistics tab at the top of the Overview page. Crash Statistics offers an overview of the statistics of all crashes, as well as a graphic representation of selected crash metrics, in a selected time period. You can select the time period and the crash filters you want to apply in the relevant dropdown menus.

crashes4.png

Crash Statistics Widgets

The collection of widgets on the Crash Statistics View shows you more details about crashes in your app, including:

  • Affected Users: Number of users that were affected by the crash, expressed as a percentage of the total number of users. The number of affected users will reduce only when users upgrade to the app version, that is higher than the version for which you resolved the crash. The number of users is also shown within the widget.
  • Resolution Status: Percentage of the crashes that have been resolved over the total number of crashes that have occurred. The number of resolved crashes is also shown within the widget.
  • Crash Fatality: Number of fatal crashes, expressed as a percentage of the total number of crashes that have occurred. The number of crashes that were fatal is also shown within the widget.
  • Top Platforms: Details of the top platforms on which crashes have occurred. The number of users that have faced a crash on each platform is also shown within the widget.
  • New Crashes: Number of crashes that have not yet been viewed.
  • Reoccurred Crashes: Number of crashes that have occurred multiple times.
  • Revenue Loss: Value of revenue potentially lost as a result of crashes occurred on any Revenue Events.
  • Latest App Version: The details of the latest version of your app.

Crash Statistics Graph

The Crash Statistics Graph shows specific metrics for the selected period, as well as the previous period, for the selected Crash Filters. The previous period is the period stretching over the exact number of days as in the selected period, and occurring just prior to the selected period. To populate data in the graph, you should first set up a time period you want to analyze by using the dropdown above the graph. Next, set the filters you want to apply using the dropdown next to the time period. This will then populate the widgets and the graph with the below information:

  • Total Occurrences: Total number of crashes or crash groups occurrences for the applied filter.
  • Unique Crashes: Number of crashes (fatal or non-fatal) that occurred uniquely. Only the first occurrence of the crash is recorded.
  • Crashes/Session: Number of crashes for the applied filter occurring per session, expressed as a percentage.
  • Crash Free Users: Number of users who have not experienced a crash for the applied filter, expressed as a percentage of the total number of users within the relevant time period.
  • Crash Free Sessions: Number of sessions during which the selected crash did not occur, expressed as a percentage of the total number of sessions within the relevant time period.

You can view any of the widget data on the graph for the selected and previous periods by clicking on the relevant widget.

Crash Details

To view the details of any crash group, simply click on the crash group in the Crash Groups table.  The segmentation that you have applied to the crash group will be visible at the top of the Crash Details page, next to Segmentation Applied. If you want to change this segmentation to see the details of any other combination of filters, you can go back to the Crash Groups page by clicking on Back at the top left corner of the page.

crashes2.png

Widgets, Stack Trace, and Comments

Under the Segmentation Applied information, you will see a detailed View of the relevant Crash Group, including:

  • Platform: Platform on which the selected crash type has occurred.
  • Occurrences: Number of times the selected crash type has occurred.
  • Affected Users: Number of users affected by the selected crash type.
  • Crash Frequency: Fraction representing the number of times the selected crash type occurred, over the total number of sessions.
  • Latest App Version: The latest app version on which the selected crash type may have occurred.

Under these details, you can see the Stack trace of the selected crash type. Click on Comments at the top left of the table to see comments left by others on the crash type.

Crash Metrics

Under these widgets, you will see other, crucial metrics related to the crash, including:

  • RAM: Average amount of RAM used in the device when the selected crash occurred. Minimum and maximum values (as percentages) are also shown.
  • Disk: Average Disk space used in the device when the selected crash occurred. Minimum and maximum values (as percentages) are also shown.
  • Battery: Average battery level of the device when the selected crash occurred. Minimum and maximum values (as percentages) are also shown.
  • Running: Average running time of your application before the selected crash occurred, expressed in minutes/seconds. Minimum and maximum values (as percentages) are also shown.
  • Session(s): Average number of sessions that a user initiated until the selected crash occurred.
  • Rooted/Jailbroken: The percentage of devices that were rooted or jailbroken when the selected crash occurred.
  • Crashed When Online: The percentage of devices that were online when the selected crash occurred.
  • Crashed While Muted: The percentage of devices that were muted when the selected crash occurred.
  • Crashed in Background: The percentage of devices in which the selected crash occurred in the background and not when in active use.

Fatal Crash Occurrences Graph

crashes3.png

Below the Crash Metrics section, you will see details about fatal crash occurrences, displayed through a graph. You can select the filter by which you want to view fatal crash occurrences, such as by app, by platform, by city, and so on. You can also zoom in to any of the data by clicking on the magnifying glass at the top right corner of the graph.

Crash Occurrences Table

In the next section of the Crash Details View, you can see details of crash occurrences, split by users. Viewable in tabular form, this section has one row for each user, and includes details of:

  • Crashed: When the user last faced this crash.
  • OS Version: The OS version of the device that the user was using when the crash occurred.
  • Device: The details of the device the user was using when the crash occurred.
  • App Version: The version of the app installed by the user and on which the crash occurred.
  • User: The name/ID of the user.

You can determine the list of crash types to see by selecting any option from the dropdown in the top left corner of the table. You can select crashes seen on all platforms, specific platforms, by app version, and more.

Click on any row to see more details of the crash faced by the specific user, including:

  • Build Info
  • Device
  • Device State
  • Custom Data
  • Stack Trace
  • Event Logs (i.e., the list of all events up to a certain duration before and after the crash. This can be configured from Settings > Crashes)
  • SDK Logs (i.e., the list of data incoming from the SDK, as per your SDK implementation)

Working With the Data

You can also undertake the below actions on the data within this table:

  • Download: You can download a Crash Occurrences report by clicking on the downward arrow at the top right corner of the table.
  • Search: Search for a specific user and/or crash occurrence by using the Search Bar at the top right corner of the table.
  • See User Details: Get a complete user profile of the user who faced the crash by clicking on the right arrow next to any user detail in the User column.

Manage Symbols

It is shown under Crashes/Errors, and you can add Debug Symbol File, manage symbols by deleting, downloading, and editing. 

Time for Crashes to Appear in Countly

Unlike other crash reporting and monitoring tools, Countly SDKs send crash information as soon as possible and before the app is completely terminated. If the information cannot be sent at this time for any reason, it is stored to be sent on the next app launch. This means that you can see crashes in Countly immediately, assuming the user has an active internet connection when the crash occurs.

This method is different from other crash reporting tools, which send crash reports when the application is opened again after the crash. The biggest disadvantage with this method is that if a user does not open your application again, the corresponding crash information that caused this behavior is never sent.

Storing Crash Reports in Server Database

By default, all crash reports are stored in Countly MongoDB collection app_crashes{APP_ID}, where APP_ID is the ID of the corresponding application. The stack trace is stored in the error property. All separate reports/occurrences are also stored in the same collection.

Inside app_crashgroups{APP_ID}, where APP_ID is the ID of your app, there is information about error groups. Same error reports are collected into one group. There, in error property, there is a stack trace of the last error report or occurrence, and that is what you see in Countly.

Forcing Crashes

Countly SDKs currently do not have any method to force crashes, but it is really easy to do this with a few lines of code.

In iOS

To force crashes in iOS, copy and paste this snippet of code:

NSArray* array = @[@"one",@"two",@"three"]; 
NSString* crashHere = array[5];

In Android

To force crashes in Android, copy and paste this snippet of code:

String array[] = {"one", "two", "three"};
String crashHere = array[5];

Status of Crashes

Status of Crash Marked as Resolved but Reappearing

When you mark a crash as resolved, you mark it resolved for a specific version. If the crash happens again on the same version or on a lower version, it still stays resolved. However, if the crash happens again on a version that is higher, the crash status is changed to 'Reoccurred'.

Status Marked as Hidden but Crash Reappears

If you mark the crash as hidden, then it stays hidden no matter what.

Duplication of Crash that Been Resolved in One Version but Appears in Another

The effect of this depends. If the code was changed a lot between versions, then it might be a new crash. However, if the code remained mostly the same and has a similar stack trace, then it would be the same crash.

FAQ and Troubleshooting

How do I use custom logging?

On iOS you need to use the crashLog: method:

[Countly.sharedInstance crashLog:@"custom crash log"];

On Android there is Countly.addCrashLog():

Countly.sharedInstance().addCrashLog("This is custom log example number " + 1);

What is a fatal and non-fatal crash?

Fatal crashes are your app's unhandled crashes, which resulted in the user having to exit the app. These are collected automatically and reported to the Countly server, if you enable this option in SDK.

Non-fatal crashes are crashes that you handled yourself in the app (like through try and catch blocks) but that you can still, optionally, report to the Countly server for later examination.

Are crashes grouped?

Yes, we have a method that groups crashes so similar crashes are populated under the same group.

 

Looking for help?