dropwizard/metrics — pull request #558 by engineerMike (2014-04-04 10:47:24+00:00)
Title: Make MetricRegistry extendable so that clients can use specialized metrics

(This PR is a follow-up of thread on metrics user group: https://groups.google.com/forum/#!searchin/metrics-user/sampling/metrics-user/aaI_eDuor_I/R41D-4MufOsJ)

This PR introcudes changes that allow clients of Metrics library to create their own specialized versions of MetricRegistry that could handle client-specialized versions of metrics e.g. specialized Timer.

In particular, in our case we want to introduce the notion of sampling (downsampling) for metrics. The reason for that is that in our high performance services we observe significant drop in performance when we use timers. The drop we observe varies from few up to 15%. The latter figure relates to the case where service covered by timer returns very simple response.

The changes proposed in this PR enable client of metrics library to create a specialized version of MetricRegistry (as subclass) that can create and register specialized versions of metrics (also using subclassing). For that we need access to getOrAdd() from subclasses.

When it comes to another change with Context access modifier:
This change is required as specialized version of Timer class may require to have different behaviour for Timer.Context. In specialized version of Timer we have to subclass so that new timer can be registered and then picked up for reporting purposes. However inheritence requires that our new timer returns Context on time() call. Currently, as Timer.Context has only private constructor it cannot be subclassed.

In our case we created NoOpContext context that does not perform any operation, and as a result time is not measured. Our SampledTimer returns NoOpContext always but every N-th time (N is sampling factor) where normal Context is returned.

Alternative approach would require making Context an interface (as here: https://github.com/engineerMike/metrics/commit/68e2c355ccd7b6a2cde391b221d870188ed92459). But it is more invasive approach.

In future we consider putting together metrics-sampling plugin that would contain all logic around sampling -- especially if others need that feature (let us know!). It could be maintained separately as Ryan's metrics-spring (https://github.com/ryantenney/metrics-spring) or merged.