Runtime performance monitoring made easy

JETM: One minute tutorial

This short tutorial explains in one minute the basic features of JETM performance monitoring. It assumes you have read basic concepts before. For more advanced features (such as declarative performance monitoring) see advanced concepts and five minute tutorial.

Step 1: Download dependencies

This following demo requires the JETM core that is available here. Download the currently stable JETM release, expand it and add lib/jetm.jar to your project classpath.

Alternatively you can download all tutorial sources including its dependencies with JETM samples. The sources are located at tutorial/one-minute. Furthermore if you have a valid ant installation you can execute the tutorial examples from the command line.

Step 2: Add measurement points to source code

Lets assume you have service class called BusinessService you want to monitor performance whise. The class contains the two public methods someMethod and nestedMethod whereas nestedMethod is called from within someMethod. To monitor their execution performance we add two measurement points manually: One around the business code in nestedMethod, the other around the business code in someMethod.

The example below shows the resulting code fragment that is also available here.

public class BusinessService {

  private static final EtmMonitor etmMonitor = EtmManager.getEtmMonitor();

  public void someMethod() {

    EtmPoint point = etmMonitor.createPoint("BusinessService:someMethod");

    try {

      //
      // some business code
      //

      nestedMethod();

    } finally {
      point.collect();
    }
  }

  public void nestedMethod() {

    EtmPoint point = etmMonitor.createPoint("BusinessService:nestedMethod");

    try {

      //
      // some business code
      //

    } finally {
      point.collect();
    }
  }
}

The method createPoint() is used to retrieve a monitoring object and takes one arguments: a symbolic name for the code fragment to be monitored. The created EtmPoint is responsible to maintain and collect execution statistics. There are several ways to access an EtmMonitor instance. The example above uses an EtmManager which pretty much works like log4j Logger or commons-logging LogFactory.

Step 3: Run business code and visualize results

We just extended our BusinessService with Measurement Points, so we are ready to analyse its performance. Therefore we need some code that calls BusinessService methods:

public class OneMinuteTest {

  private static EtmMonitor monitor;

  ...

  public static void main(String[] args) {
    // configure measurement framework
    setup();

    // instantiate business service
    BusinessService service = new BusinessService();

    // execute business logic

    service.someMethod();
    service.someMethod();
    service.someMethod();
    service.nestedMethod();

    // visualize results
    etmMonitor.render(new SimpleTextRenderer());

    // shutdown measurement framework
    tearDown();
  }


  private static void setup() {
    BasicEtmConfigurator.configure();
    monitor = EtmManager.getEtmMonitor();
    monitor.start();
  }

  private static void tearDown() {
    monitor.stop();
  }

}

The class OneMinuteTest now executes BusinessService methods and renders the result using a SimpleTextRenderer. This renderer writes aggregated performance results to Java standard-out using the default locale. Please note that there is setup and tear down code that initializes and stops performance monitoring.

The execution of this code fragment should create an output like this (alternatively execute ant demo in the tutorial directory to get the same result):

|------------------------------|---|---------|--------|--------|---------|
|      Measurement Point       | # | Average |   Min  |   Max  |  Total  |
|------------------------------|---|---------|--------|--------|---------|
| BusinessService:nestedMethod | 4 |   3.556 |  1.029 |  6.075 |  14.224 |
|------------------------------|---|---------|--------|--------|---------|
| BusinessService:someMethod   | 3 |   5.881 |  5.079 |  7.460 |  17.642 |
|------------------------------|---|---------|--------|--------|---------|

That's it! Well, almost. There are some optional features you may be interested in.

Step 4: (Optional) Alter runtime configuration

An EtmManager will always return the default performance monitoring setup unless it's configured using an BasicEtmConfigurator or XmlEtmConfigurator. Within this tutorial we demonstrate two BasicEtmConfigurator options.
Enable execution path recording

In the example above BasicEtmConfigurator.configure() selects a FlatMonitor for measurement collection. Often this EtmMonitor provides enough details to understand the performance characteristics of your application. However it might be important to record execution paths as well. The so-called NestedMonitor may be enabled with BasicEtmConfigurator.configure(true).

The output will change as follows:

|-------------------------------|---|---------|--------|--------|---------|
|       Measurement Point       | # | Average |   Min  |   Max  |  Total  |
|-------------------------------|---|---------|--------|--------|---------|
| BusinessService:nestedMethod  | 1 |   7.116 |  7.116 |  7.116 |   7.116 |
|-------------------------------|---|---------|--------|--------|---------|
| BusinessService:someMethod    | 3 |  10.692 |  3.544 | 19.305 |  32.075 |
|  BusinessService:nestedMethod | 3 |   5.095 |  1.060 | 12.146 |  15.285 |
|-------------------------------|---|---------|--------|--------|---------|
Select timer implementation

By default EtmManager will record execution times using the best available ExecutionTimer. Currently available measurement timers are JDK1.5 nano timer, Sun Misc HighRes Timer and System.currentTimeMillis. You may select a specific ExecutionTimer by providing an concrete timer instance to BasicEtmConfigurator.configure().

For example BasicEtmConfigurator.configure(true, new DefaultTimer()) will change the output as follows (note change in resolution):

|-------------------------------|---|---------|--------|--------|---------|
|       Measurement Point       | # | Average |   Min  |   Max  |  Total  |
|-------------------------------|---|---------|--------|--------|---------|
| BusinessService:nestedMethod  | 1 |   5.000 |  5.000 |  5.000 |   5.000 |
|-------------------------------|---|---------|--------|--------|---------|
| BusinessService:someMethod    | 3 |   8.000 |  5.000 | 12.000 |  24.000 |
|  BusinessService:nestedMethod | 3 |   4.000 |  2.000 |  7.000 |  12.000 |
|-------------------------------|---|---------|--------|--------|---------|

For more options see BasicEtmConfigurator and XmlEtmConfigurator Javadoc.

Next: Advanced concepts.