1. Marshall Pierce
  2. jersey2-metrics



Build Status


Made with an IntelliJ license for open source projects courteously provided by JetBrains.

What is this?

It's a Jersey 2 ApplicationEventListener that captures information about your request processing in Metrics. There's a similar project for Jersey 1 if you're still on Jersey 1.

Why do I want it?

Suppose you have a resource like this:

public class SampleResource {
    public String getCoolData() {
        return calculateTheCoolestData();


This library will make it so that you will automatically have the following metrics calculated for requests that invoke SampleResource#getCoolData() (and any other resource methods):

  • A Timer to track request handling time
  • A Counter for each status code that your resource returns (one for 200, one for 500, etc)

How do I use it?

First, add your dependencies in build.gradle or your dependency mechanism of choice:

compile 'org.mpierce.jersey2.metrics:jersey2-metrics-core:LATEST_RELEASED_VERSION'

Then, when you're initializing your Jersey ResourceConfig, include a MetricsAppEventListener:

MetricsAppEventListener listener = new MetricsAppEventListener.Builder(metricRegistry).build();

This will use all default configuration; see below for the various options.


There are several different avenues for altering how metrics are created.


A MetricArbiter lets you control which requests have metrics calculated for them.

  • FixedMetricArbiter allows the user to say "always yes" or "always no" for a given metric type. The default configuration uses this implementation in "always yes" mode.
  • AnnotationArbiter in jersey2-metrics-annotation-arbiter uses the @ResourceMetrics annotation (from this project) on resource classes or methods to control whether metrics will be created.
  • StockAnnotationArbiter in jersey2-metrics-stock-annotation-arbiter uses the stock @Timed annotation from the core Metrics project: if and only if the annotation is present, a Timer will be created.

Use MetricsAppEventListener.Builder#withArbiter() to configure which arbiter you use. If none of the above suit you, you can always write your own.


A MetricNamer governs how metrics are named.

Use MetricsAppEventListener.Builder#withNamer() to configure which namer you use. Like MetricArbiters, if none of the above suit you, you can always write your own.

Custom reservoirs

Timers have a reservoir under the hood. Different reservoirs have major effects on how your latency measurements are handled. By default, HdrHistogramReservoir is used as it's likely to be a good choice for most needs.

Use MetricsAppEventListener.Builder#withReservoirSupplier() to configure which reservoir implementation you use.

Doesn't Metrics already ship something like this?

Yes it does (metrics-jersey2) but it's pretty limited:

  • It will not generate a metric unless you annotate a method. There's no way to implement a global metric policy, so you'll need to type @Timed a lot.
  • It doesn't support global naming policies, You have to manually set the name of each annotation if you don't like what it makes for you out of the box.
  • It doesn't support custom reservoirs. You almost certainly want to use a non-default reservoir like this one.

By using StockAnnotationNamer and StockAnnotationArbiter you are effectively recreating metrics-jersey2 for timers. metrics-jersey also supports @Metered and @ExceptionMetered, which this library does not. If this is an important feature for you, file an issue!