Metrics

Knowing what your application is doing in production is critical for any team. Generally this is accomplished via a lot of logs; sometimes with specialized dashboards. An important tool to gather information is collecting metrics: metrics are (generally) numeric values exposing an information about the state of your application. For instance, common metrics that are tracked include the number of requests, the time elapsed for processing a request, the number of exceptions, and so on. Metrics can give you detailed insight in what is going on in your applications; generally you are better off with more information rather than less.

Dropwizard’s metrics, commonly known just as Metrics, is a Java library that helps collecting and exposing metrics. It allows you to register a lot of kinds of different metrics and then expose them in various ways; for instance, you can periodically log them, generate a csv file, expose them via http or via JMX. You can also send them to a dedicated metrics collector such as Ganglia or Graphite, which can be used to generate dashboards including multiple applications.

Here we’ll give a quick overview of what Metrics can do; you should check out its getting started page and then the complete manual.

Types of metrics

To get started, you need an instance of MetricsRegistry; creating it is simple and it’s probably something you will want to do in your dependency injection framework, if you use one. In any case, it’s trivial to create it by hand:

MetricRegistry metrics = new MetricRegistry();

Counters

One of the simplest kind of metric is a counter, which is simply an integer. Counters start at zero and can be used to register the number of times something happens; for instance, an exception is thrown or a request fails. Creating and using one is quite simple:

Counter failures = metrics.counter(name(RequestHandler.class, "failures"));
failures.inc();

Gauges

Gauges are metrics that return a value. They can be used to expose the current state of something; for instance, you might have a gauge representing a Guava’s cache’s current hit rate:

Cache myCache = CacheBuilder.newBuilder().recordStats().build();
metrics.register(name(MyCacheUser.class, "cache-hit-rate"), new Gauge<Double>() {
    @Override
    public Double getValue() {
        return cache.stats().hitRate();
    }
});

Meters

Meters record the frequency of events, recording the mean from the metrics’ creation. Since this is generally not very useful (if your application only receives requests during business hours, knowing the average - which includes the night - is pointless), meters will also automatically record the 1 minute, 5 minute and 15 minutes moving averages. Creating a meter is again very simple:

Meter failures = registry.meter(name(FailureTracker.class, "failures"));
failures.mark();

Timers

Timers can record the frequency and duration of requests; similarly to meters, they keep various percentiles and moving averages. Here’s a simple example taken directly from the manual:

final Timer timer = registry.timer(name(WebProxy.class, "get-requests"));

final Timer.Context context = timer.time();
try {
    // handle request
} finally {
    context.stop();
}

Final words

Adding metrics to your application can be invaluable in development as well as production environments: knowing precisely what your application is doing; how many requests is getting; how much are cached used; is the only way to actually track down performance issues or measure how much impact changes have had.