Documentation / Metric Types

Metric types

There are 4 main types of metrics that are supported.

  • Timers - monitor timed events like method execution time and request processing time.
  • Gauges - monitor resources like memory (used, max etc) and threads (active, max etc).
  • Counters - monitor discrete events like user login or error logged.
  • Value - monitor events that have a value like 'bytes sent' or 'lines processed'.
Quick links:

TimedMetric

Collects and provides statics for a timed event. Most typically collects execution statistics for a method. TimedMetric has the ability to keep separate statistics for success and error execution. It is generally useful to know which methods are invoking errors and differences in execution time of errors versus successful execution.

// Declare the metric (typically as a static field)
static final TimedMetric timedUserLogin = MetricManager.getTimedMetric(MyService.class, "performLogin");

public void performLogin() {

  long startNanos = System.nanoTime();

  try {
    ...

  } finally {
    // Add the event to the success statistics
    timedUserLogin.addEventSince(true, startNanos);
  }
}

@Timed

If you can use the @Timed annotation and enhancement to automatically add a TimedMetric.

Output example:
 23:59:38, tm, org.test.MyService.performLogin, count=1, avg=954, max=954, sum=954, dur=31, err.count=0

BucketTimedMetric

Used to collect timed metrics but puts the statistics into millisecond time ranges (buckets).

In providing millisecond bucket ranges of 200, 400, 600 this will create 4 buckets to put the execution statistics into. The first range will be for all events that take between 0 and 200 milliseconds, the second range will be for all events that take between 200 and 400 milliseconds, the third range will take events that take between 400 and 600 milliseconds and the last bucket takes all events that take longer than 600 milliseconds.

The general purpose of using a BucketTimedMetric over a TimedMetric is that it can provide an insight into how the execution times are statistically distributed. For example, a method execution might have 2 paths with one hitting a cache and generally a lot faster. In using 2 or more buckets you might get a more representative view of the 2 distinct execution paths and monitor the slow non-cached execution path more accurately.

// Declare the metric with 4 bucket ranges of:
//    0 - 100 milliseconds
//  100 - 200 milliseconds
//  200 - 300 milliseconds
//  300+      milliseconds

static final BucketTimedMetric timedUserLogin =
     MetricManager.getBucketTimedMetric(MyService.class, "performLogin", 100, 200, 300);

public void performLogin() {

  long startNanos = System.nanoTime();

  try {
    ...


  } finally {
    // Add the event to the success statistics
    timedUserLogin.addEventSince(true, startNanos);
  }
}

@Timed

If you can specify buckets on the @Timed annotation then enhancement will define a matching BucketTimedMetric.

CounterMetric

Metric based on a counter (long value) that counts discrete events like 'user logged in'.

// Declare the counter (typically as a static field)
static final CounterMetric loginCounter = MetricManager.getCounterMetric(MyService.class, "userLogin");

public void performUserLogin() {

  // increment the counter
  loginCounter.markEvent();
  ...
}

ValueMetric

Metric used when the event has a value like 'bytes sent' or 'lines processed'.

// Declare the metric (typically as a static field)
static final ValueMetric bytesSentMetric = MetricManager.getValueMetric(MyService.class, "bytesSent");

public void performSomeIO() {

  long bytesSent = ...

  bytesSentMetric.addEvent(bytesSent);

}

GaugeLongMetric

Metric based on an underlying gauge that reports long values.

  class ThreadCountGauge implements GaugeLong {

     public long getValue() {
       return threadMXBean.getThreadCount();
     }
   }

  // register the gauge
  GaugeLongMetric gauge = MetricManager.register("jvm.thread.count", threadCountGauge);

  // Note that typically you register and don't need the returned GaugeLongMetric
  // instance. The MetricReporter will periodically get the current gauge value.

GaugeDoubleMetric

Metric based on a gauge returning double values.

  class FreeMemoryGauge implements GaugeDouble {

    public double getValue() {
      return mxBean.getFreeMemory() / mxBean.getTotalMemory();
    }
  }

  GaugeDoubleMetric gauge = MetricManager.register("jvm.memory.pctfree", freeMemoryGauge);

Built in JVM gauges

Avaje Metrics automatically registers some core jvm gauges for memory, threads, garbage collection, OS load average and system uptime.

Output example:

  00:00:51, lg, jvm.gc.ps-marksweep, count=4, time=1556
  00:00:51, lg, jvm.gc.ps-scavenge, count=48, time=6811
  00:00:51, dg, jvm.memory.heap, pct=23.0, init=61.75, used=210.21, committed=379.5, max=878.5
  00:00:51, dg, jvm.memory.nonheap, pct=4.0, init=23.44, used=9.12, committed=23.44, max=214.0
  00:00:51, dm, jvm.os.loadAverage, value=1.17
  00:00:51, dm, jvm.system.uptime, value=0.0
  00:00:51, lg, jvm.threads, current=5, peak=5, daemon=4