The revolution will be verbosely {,b}logged

Monitoring Android Apps Using SolarWinds Cloud Monitoring Tools

Posted by Jason Skowronski on

There are millions of Android applications already available on the app store, with thousands more being launched every month. Unlike desktop programmers, however, Android app developers may face many challenges, such as slow internet speeds, small screens, and a keyboard.

If an app doesn’t perform well, there is nothing to stop a user from uninstalling the app and moving on. To prevent this, you must be aware of ongoing issues with the application and any backend service integrations. We’ll show you how to monitor and troubleshoot Android application issues using the SolarWinds cloud monitoring tools, including PapertrailTM for cloud-based log management and Pingdom® for uptime monitoring.

Why Monitoring Problems on Mobile Apps Are Important

In this competitive world, there are alternatives for almost all applications. If an app freezes, crashes, or its response time is slow, the user can get frustrated and uninstall the app. Users may also write negative reviews, resulting in fewer downloads.

To prevent this, it is important to monitor your apps and track data to determine the affected components and versions of the application that are causing problems. Monitoring can offer deep diagnostic data on the HTTP requests, error stack traces, request time, response time, and even informational data. This makes it easy to find the root cause of the problem and to fix it quickly.

Native Error or Crash Handling on Android

The most basic way to catch errors in Android apps is using a try/catch block. When an exception is thrown in the try block, the catch block executes and handles the error. For example, you may want to report the error to a tracking service.

try {
  String test = null;
  test.toString();
} catch(Exception e) {
  e.printTrace();
  // Place error reporting service here
}

An Android app crashes whenever uncaught exceptions cause unexpected exits. Using a global error handler can catch these unhandled exceptions.

In Android, you can create a global error handler by implementing the UncaughtExceptionHandler interface which gives you the unimplemented method named “uncaughtException.” This method lets you catch those exceptions and provide a message to the users. You can also send those exceptions to a logging service like Papertrail so your team can quickly fix them. Here’s how you can create your own error handler:

public class ReportHelper implements Thread.UncaughtExceptionHandler {
  private Context context;

  public ReportHelper(Context context) {
    this.context = context;
  }

  @Override
  public void uncaughtException(Thread thread, Throwable ex) {
    ex.printTrace();
    // Place error reporting service here
  }
}

Monitor Logs with Papertrail

Papertrail is a cloud-based log management system through which a user can analyze app behavior across devices. It allows you to monitor the Android logs in real time. You can analyze the server errors and client errors along with the device name information.

You can easily search for the logs you are interested in by defining the search query. It will list the logs that match your query. The screenshot below shows the results when we search the term “ArrayIndexOutOfBoundsException”.

Search query log.

You can also create alerts to notify you when there is a big change in the system, such as a spike in error messages. You just need to set the search term. You can get the alerts on various endpoints like email, Slack, Hipchat, and more. Now your team will know immediately when there is a problem and can respond quickly.

Papertrail errors alert.

Additionally, sudden spikes in the number of log events occasionally happen when a large number of people are affected, or an error occurs in a loop and repeats. As a result, this generates a large volume of log messages, which can flood your account. Papertrail can solve this difficulty as it is equipped with a log flood detection feature. Papertrail can notify you if your log rate is higher than expected.

Log flood detection.

If you set a log rate in your Papertrail account, and the log count increases from the set limit in at least 10 minutes, then Papertrail will notify everyone who is interested in getting the notifications about the sudden increase in the log rate.

Set Up Papertrail

You can send Android logs to Papertrail by using the logback-syslog4j method or the logback-android method. Papertrail recommends the logback-syslog4j appender because it includes TCP, TCP with TLS, and Google App Engine support, as well as relying on syslog4j for message transmission. In order to use logback in the app, you need to follow some simple steps.

Step 1: Add the following to the app’s Gradle dependencies list:

compile 'org.slf4j:slf4j-api:1.7.25'
compile 'com.github.tony19:logback-android:1.1.1-12'
compile ('com.papertrailapp:logback-syslog4j:1.0.0') {
    exclude group: 'ch.qos.logback'
}

Step 2: Update your configuration file to include the example shown below. Don’t forget to replace logsN and XXXXX with the details shown under Log Destinations in Papertrail. To log the events with the appropriate app name, you can give a custom app name in the configuration below. For this, replace YOUR_APP with your desired app name.

<configuration> 
  <appender name="syslog-tls" class="com.papertrailapp.logback.Syslog4jAppender"> 
    <layout class="ch.qos.logback.classic.PatternLayout">
      <pattern>%d{MMM dd HH:mm:ss} Android YOUR_APP: %-5level %logger{35} %m%n</pattern>
    </layout>

    <syslogConfig class="org.productivity.java.syslog4j.impl.net.tcp.ssl.SSLTCPNetSyslogConfig"> 
      <host>logsN.papertrailapp.com</host> 
      <port>XXXXX</port> 
      <sendLocalName>false</sendLocalName>
      <sendLocalTimestamp>false</sendLocalTimestamp> 
      <maxMessageLength>128000</maxMessageLength> 
    </syslogConfig> 
  </appender>

  <appender name="async" class="ch.qos.logback.classic.AsyncAppender"> 
    <appender-ref ref="syslog-tls" /> 
  </appender>

  <root level="INFO"> 
    <appender-ref ref="async" /> 
  </root> 
</configuration>

Step 3: If ProGuard is enabled with minifyEnabled and is set to true in the app, then add the snippet below to the proguard-rule.pro file.

-keep class org.productivity.java.syslog4j.** { *; }

Otherwise, ProGuard removes the Syslog4j classes, resulting in a runtime error:

java.lang.ClassNotFoundException: Didn't find class "org.productivity.java.syslog4j.impl.net.tcp.ssl.SSLTCPNetSyslogConfig"

Send Android Logs

We have created an example that is generating an exception and sending it to Papertrail. The example below is generating a “null pointer exception” while invoking the toString() method on the “test” variable.

public class MainActivity extends AppCompatActivity {
  private Logger log;
  private Context context;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    context = this;
    log = LoggerFactory.getLogger(MainActivity.class); 
    try {
      String test = null;
      test.toString();
    } catch (Exception ex){
      log.error("Client error : ",ex.getMessage());
    }   
  }
}

It generates the below exception log, which includes the date and time of logging, log level, and exception details.

10-11 11:49:18.892 4145-4145/com.demo E/Client error : Attempt to invoke virtual method 'java.lang.String java.lang.String.toString()' on a null object reference

Many mobile apps today also include backend services. With Papertrail, errors are generated by backend services. In the example below, you can see we have used a test URL that returns an “Internal server error” with the status code 500.

private class GenerateServerError extends AsyncTask<String, Void, Void> {
  protected Void doInBackground(){
    try {
      HttpClient client = new DefaultHttpClient();
      HttpGet httpget = new HttpGet("http://httpbin.org/status/500");
      ResponseHandler<String> responseHandler = new BasicResponseHandler();
      client.execute(httpget, responseHandler);
    } catch (ClientProtocolException e) {
       log.error("Server Error:",e);
    } catch (IOException e) {}
    return null;
  }
}

This code results in the below error message.

10-11 17:20:50.127 8181-8212/com.demo E/Server Error: org.apache.http.client.HttpResponseException: INTERNAL SERVER ERROR    

Monitoring a Backend Service Using Pingdom

Mobile app functionality often relies on backend services such as a database, cache, or scheduler. Keeping these services running is very important, especially when your system is your production environment. When there is a problem, an alert should inform you about the incident right away.

With SolarWinds Pingdom, you can monitor the availability of your website and backend services. You can also track uptime, response time, transactions, and more. To do this you need to create uptime checks in Pingdom. It’s as simple as adding a name for your check, specifying the interval for how frequently the check runs, and the URL to check.

Add uptime check.

Pingdom provides an alerting feature to send notifications when one of your checks fails. When an outage occurs, Pingdom notices and alerts the right person. Below, we can see an example email alert. It is notifying us that the server is returning a 500 error.

Pingdom alert sent via email.

Conclusion

SolarWinds cloud monitoring tools like Papertrail and Pingdom allow you to notice problems in Android apps quickly and deliver a better user experience. This requires that you monitor not just the application itself, but also any backend services that integrates with it. Papertrail allows you to monitor logs in real time on both the client and server side. Pingdom is able to monitor your backend services for availability. Sign up for free trials of Pingdom and Papertrail today.