How to monitor JAXRS/Jersey applications

If you nowadays visit a conference, you still might get into contact with sessions where people are talking about monitoring or at least some aspects of it and ALM (application lifecycle management) is a really important discipline a team or project should should take into account right from the beginning and no, this doesn’t mean that you should trim or optimize prematurely, but to have an eye on it. Next to the developers and operators we can identify many more stakeholders who are interested in the data, but generally they prefer a different view on the data.

  • Who is the audience, who uses the API in what version?
  • How can I economize resources, but for specific cases only?
  • How can I use the data to prevent accidents or control specific nodes?

The code can be found at Github and this article shall, simply spoken, show the motivation behind it. So, in one sentence I would say:

We want fine grained statistics about things that happen without writing much integration code and to partition the data at runtime using the provided input.

Enabling monitoring ‘always’ require us to follow the same pattern (do something before and optionally do something after), so it would be nice to simply not do the same things over and over again. Monitoring can be seen as a classical cross cutting concern and even if we loose some control at implementation level, we can profit on less maintenance effort and a better system design – which is a good trade in my opinion.

When I hear the words ‘cross cutting concerns’ then instantly AOP (aspect oriented programming) comes into my mind and those techniques shall pave the way as described in the sentence above. It can be further used independently of the underlying technology – of course we need some technology glue to wire the aspects, but this must generally be done only once.

Many public APIs follow the REST pattern today. So we decided to go with Jersey first as it’s a great framework for building enterprise REST services. Jersey uses HK2 internally and you can vary almost every part at runtime with a fluent java API – If you know Google Guice then you might get an impression now. HK2 supports AOP through the libraries from the AOP Alliance and you can hook this process easily following the guidelines of from aop-example. That’s a pretty good news and a mighty joinpoint for metrics, a quality library to gather runtime statistics.
Right now, our recipe contains Jersey, Metrics, AOP, and Java annotations as markup and if we plug everything together we achieve something like this:

    @GET
    @Metric (
        timers     = @Timer,
        histograms = @Histogram (value = "#size", measure = BambooResponseSize.class),
        counters   = @Counter   (value = "{color}", kind = Kind.Error)
    )
    @Path ("{name}")
    public String echo (@PathParam ("name") String name, @QueryParam ("locale") String locale, @DefaultValue ("Green") @QueryParam ("color") Color color) {
        validate (color);
        return service.call (name + "::" + locale);
    }

One nice thing to mention is, that everything managed by HK2 can be annotated and therefore measured – including resource methods and services from the DI container – fine grained control at method level :).

So what do I mean with a partition at runtime then?
You can find some the JAXRS annotations in the previous example, e.g. PathParam, QueryParam and of course, Jersey knows the interpretation of the parameters, but do we know as well? Yes and that’s pretty awesome, as it allows us to

  • build metrics which are partitioned by customer levels : .., silver, gold, platinum
  • build metrics for versioned APIs: /v1/, …, /v9/ — anyone using v1, costs?
  • build metrics to track clients by geography, cookie, header
  • build metrics that measure errors only
  • build metrics for if-you-can-name-it-you-can-measure-it things.
    A conversion takes place prior, so you can run every custom evaluation beforehand: userguide

And thats’ what I really like the most 🙂 – You have access to runtime values from ALL services, resources managed by Jersey/HK2 to configure the usecase you want.

If you like to contribute or participate on items mentioned on the roadmap or issue something, thats not on the roadmap 🙂 then feel free to visit us at Github, or even if you want to try out the example project to get a first impression.
Feedback is highly welcome and many thanks from me to the developers of Jersey/HK2 and Metrics for their great work – nice piece of software.