Errplane

This library integrates your applications with Errplane, a cloud-based tool for handling exceptions, log aggregation, uptime monitoring, and alerting.

Installing the library

The easiest way to get started is to download the latest prebuilt jar file from errplane-<version>.jar. The library contains no 3rd party dependencies so you should be able to add it to your classpath and go. The main import you'll use is:

import com.errplane.api.Errplane;

Initializing the library

The library is initialized with the following arguments:

appKey: your app name configured in Errplane
apiKey: your api_key used to verify Errplane usage
env: the environment you are using (usually one of: production, staging, development)

With these values the library is initialized using:

boolean success = Errplane.init(appKey, apiKey, env);

success is true if none of the values passed in were null and a URL was successfully built.

Additionally, to set a session user (for single-user applications) to better trace exceptions reported to Errplane the following can be used:

Errplane.setSessionUser("string that identifies the current user");

Example Code

The example code can be found in Example Code. The example code is not built into the library since it contains environment specific code. It is intended to be used as a reference (or directly in your project if one of the available samples fits your usage scenario and environment).

Standalone Initialization Example

This example shows how to initialize Errplane and startup the ErrplaneFlusher to send reports automatically to Errplane. It is important to remember that none of the samples (e.g. ErrplaneFlusher) are included in the Errplane jar. To use the flusher simply copy-paste from the linked code. Also, this example initialization code can be found in errplaneDriver. The example assumes you have the errplane jar in your classpath.

import com.errplane.api.Errplane;
import com.errplane.examples.standalone.ErrplaneFlusher;

public errplaneDriver {

    public static void main(String[] args) {

        // try to initialize Errplane
        if (!initErrplane()) {
            System.out.println("Errplane initialization failed!");
            System.out.println("Make sure you have set the environment variables: EP_APP, EP_API, and EP_ENV!");
            return;
        }

        // fire up the flusher
        ErrplaneFlusher flusher = new ErrplaneFlusher();
        flusher.startFlusher();

        // fire up the heartbeat at the default 30 second interval
        flusher.heartbeat("errplane-java/sampleDriverHB");

        // code to run your application and send Errplane reports and exceptions goes here
        // ...
        // ...
        // ...


        // when your application is exiting stop the flusher to send all leftover reports to Errplane
        flusher.stopFlusher();

    }

    private static boolean initErrplane() {

        // you can read these out of a properties file if you prefer (or even hardcode them)
        String appKey = System.getenv("EP_APP");
        String apiKey = System.getenv("EP_API");
        String env = System.getenv("EP_ENV");
        return Errplane.init(appKey, apiKey, env);
    }
}

Play Framework 2.0+ Initialization Example

This example shows how to initialize Errplane and startup the ErrplaneFlusher to flush reports automatically within the Play Framework. It is important to remember that none of the samples (e.g. ErrplaneFlusher) are included in the Errplane jar. To use the flusher simply copy-paste from the linked code. Also, this example initialization code can be found in Global. The example assumes you have the errplane jar in your classpath.

import com.errplane.api.Errplane;
import com.errplane.examples.standalone.ErrplaneFlusher;

import play.Application;
import play.GlobalSettings;

public class Global extends GlobalSettings {

    private ErrplaneFlusher flusher;

    @Override
    public void onStart(Application app) {

        // try to initialize Errplane
        if (!initErrplane()) {
            System.out.println("Errplane initialization failed!");
            System.out.println("Make sure you have set the environment variables: EP_APP, EP_API, and EP_ENV!");
            return;
        }

        // fire up the flusher
        flusher = new ErrplaneFlusher();
        flusher.startFlusher();

        // fire up the heartbeat at the default 30 second interval
        flusher.heartbeat("errplane-java/playApplicationHB");

        // let it be known that we started up
        Errplane.report("errplane-java/playApplicationStartup");
    }

    @Override
    public void onStop(Application app) {
        // let it be known that we're going down
        Errplane.report("errplane-java/playApplicationShutdown");

        // clear Errplane reports
        flusher.stopFlusher();
    }

    private static boolean initErrplane() {

        String appKey = System.getenv("EP_APP");
        String apiKey = System.getenv("EP_API");
        String env = System.getenv("EP_ENV");
        return Errplane.init(appKey, apiKey, env);
    }
}

Basic Usage Scenario

The first thing you must do when using Errplane is initialize the library. Reports will get stored prior to initialization, but nothing gets sent until its initialized. After that you would begin reporting. After sending a number of report(...) commands it is good to flush the queued reports to the Errplane server (or flush it on a loop as is done in the standalone example and the Play Framework example ). Additionaly, you can report Exceptions when they occur. With that in mind here is a basic scenario:

import com.errplane.api.Errplane;
import com.errplane.api.TimerTask;

...

// init Errplane
if(Errplane.init(appKey, apiKey, env)) {
  // add reports
  Errplane.report("controllers/controller1");
  Errplane.report("controllers/controller2");
  Errplane.report("controllers/controller3");

  // send the reports to the Errplane server - flush also tells you how many were sent
  int numReportsSent = Errplane.flush();

  // time a long running task or potential bottleneck
  TimerTask timer = Errplane.startTimer("longTask");

  // do your applicationy stuff
  // ...

  // tell the timer you're done
  timer.finish();

  // flush it
  int numReportsSent = Errplane.flush();

  // force an exception
  String [] arr = {"one", "two", "threeButNotFour"};
  try {
    System.out.println(arr[3]);
  }
  catch (Exception e) {
    // Errplane.getExceptionData(String controller, String action, String userAgent) is a
    //   convenience method for creating an instance of com.errplane.api.ExceptionData.
    //   controller and action are expected to map to class and method respectively.
    //   userAgent specifies the client type (e.g. - browser, standalone app, mobile, ...)
    Errplane.reportException(e, Errplane.getExceptionData("YourController", "YourAction", "YourUserAgent"));
  }
  Errplane.flush();
}

Reporting

Errplane allows you to report any amount of useful numeric and context relevant data that can be used for analyzing performance and usage of your application. There are six methods used for reporting - use the methods that make the most sense for your application. For each reporting method, the name passed in to the Errplane.report() methods must be < 250 characters. The following are simple examples for each method:

import com.errplane.api.Errplane;

// simple reporting (default value of 1 is sent to Errplane)
Errplane.report("user logged in");

// reporting providing your own useful double value
Errplane.report("avg_usage_pcnt", 99.9);

// reporting providing your own useful context (uses default value of 1)
Errplane.report("problem_with_server", "Delayed Server Request");

// reporting providing your own useful context and value
Errplane.report("average_response_time", 192.75, "Average Response Time");

// reporting providing your own useful context and value
Errplane.report("average_response_time", 192.75, "Average Response Time");

Sum

Keep a cumulative sum of the values per minute (negative values will decrement the counter).

import com.errplane.api.Errplane;

// incrementing providing your own useful double value
Errplane.sum("avg_usage_pcnt", 99.9);

// incrementing providing your own useful context (uses default value of 1)
Errplane.sum("problem_with_server", "Delayed Server Request");

// incrementing providing your own useful context and value
Errplane.sum("average_response_time", 192.75, "Average Response Time");

// incrementing providing your own useful context and value
Errplane.sum("average_response_time", 192.75, "Average Response Time");

Aggregate

Aggregate values per minute, this will calculate the mean, sum and count of all data points.

import com.errplane.api.Errplane;

// aggregating providing your own useful double value
Errplane.aggregate("avg_usage_pcnt", 99.9);

// aggregating providing your own useful context (uses default value of 1)
Errplane.aggregate("problem_with_server", "Delayed Server Request");

// aggregating providing your own useful context and value
Errplane.aggregate("average_response_time", 192.75, "Average Response Time");

// aggregating providing your own useful context and value
Errplane.aggregate("average_response_time", 192.75, "Average Response Time");

Exception Reporting

There are four basic methods for reporting exceptions. Again, use the ones that make the most sense for your application. All of these examples assume exception is derived from java.lang.Exception.

import com.errplane.api.Errplane;

// basic default
Errplane.reportException(exception, Errplane.getExceptionData
        ("MyJavaClass", "myJavaMethod", "browser"));

// with custom data
Errplane.reportException(exception, "custom data for you to pass in can be json",
        Errplane.getExceptionData("MyJavaClass", "myJavaMethod", "standalone app"));

Breadcrumbs

Breadcrumbs are useful in a single-user application for providing checkpoints for your app leading up to the point where an exception is thrown. The Errplane library stores the last 10 breadcrumbs you provide and automatically sends them along when you report an exception:

import com.errplane.api.Errplane;

// assume you've inited Errplane
Errplane.breadcrumb("now");
Errplane.breadcrumb("some");
Errplane.breadcrumb("breadcrumbs");

try {
    throw new ClassCastException("Just some BCs, don't worry about it!");
}
catch (ClassCastException e) {
    Errplane.reportException(e, Errplane.getExceptionData
            ("MyJavaClass", "myJavaMethod", "gaming console")));
}

Timed Execution Reporting

Timed execution reporting allows you to report the time taken to complete a section of code. As when reporting events to Errplane, the name passed in to the Errplane.startTimer(String) method must be < 250 characters. To time execution use the following:

import com.errplane.api.Errplane;
import com.errplane.api.TimerTask;

...

// assume you've inited Errplane (or that you will before you flush)
TimerTask timer = Errplane.startTimer("fastTask");

// your code goes here

// tell the timer we're done
timer.finish();

// flush it if you don't have that running on a seperate thread
Errplane.flush();

Customizing How Exceptions Get Grouped

Under Development

Tests

Test code can be found at: Errplane Tests