I am trying to add metrics to a plain Java application using codahale metrics. I\'d like to use the @Timed annotation, but it is unclear to me which MetricRegistry it uses,
As the other answer stated, you have to have something in the application to listen for your instantiated classes and check them for the @Timed annotation.
If you're using Guice, you could use: https://github.com/palominolabs/metrics-guice
Use the built-in MetricRegistry accessed from the bootstrap parameter in the initialize method of your application class.
@Override
public void initialize(final Bootstrap<Configuration> bootstrap) {
final JmxReporter reporter = JmxReporter.forRegistry(bootstrap.getMetricRegistry()).build();
reporter.start();
}
AOP is overkill and not appropriate for use of @timed, generally speaking.
The default metrics registry writes @timed metrics to a ConcurrentHashMap and does not attach any meaningful listeners.
DropWizard Bootstrap constructor:
/**
* Creates a new {@link Bootstrap} for the given application.
* @param application a Dropwizard {@link Application}
*/
public Bootstrap(Application<T> application) {
this.application = application;
this.objectMapper = Jackson.newObjectMapper();
this.bundles = Lists.newArrayList();
this.configuredBundles = Lists.newArrayList();
this.commands = Lists.newArrayList();
this.validatorFactory = Validators.newValidatorFactory();
// returns new ConcurrentHashMap<String, Metric>();
this.metricRegistry = new MetricRegistry();
this.configurationSourceProvider = new FileConfigurationSourceProvider();
this.classLoader = Thread.currentThread().getContextClassLoader();
this.configurationFactoryFactory = new DefaultConfigurationFactoryFactory<T>();
}
So you need to build/start/register the appropriate metric registry in order to see results.
Here I use JMX:
@Override
public void initialize(Bootstrap<PayloadStorageConfiguration> bootstrap) {
JmxReporter.forRegistry(bootstrap.getMetricRegistry()).build().start();
}
That's all you need to do.
Here's an example of the output (run jconsole against your Java application/server to view JMX results):
You could also use stagemonitor-core for that. See documentation here and here. The advantage is that stagemonitor (which is free & open source btw) does not depend on any container-based AOP like Spring AOP or EJB interceptors. It uses bytecode manipulation via runtime attachment which means that you do not even have to add a -javaagent
flag to your application startup - a plain dependency is enough.
If you want to measure the execution time in a web application or in a remote EJB application, you don't even have to manually annotate your code. Also, stagemonitor offers preconfigured Grafana and Kibana dashboards.
Disclaimer: I'm one of the developers of stagemonitor
Using @Timed
doesn't actually require the use of AOP, as was previously claimed in the top-rated answer, if you're inside a container and using one of Dropwizard's instrumentation libraries. See the Jersey 2.x module for example, which you can see uses reflection (as do the others I looked at), if you read the source.
You can read up on all of these modules in the Dropwizard docs under the corresponding "Instrumenting ____" bullets.
I understand the OP was explicitly NOT working within such a container, but I wanted to offer this info, since many of us looking for this answer may be working on a modern web service that can register such resources in its runtime environment.
In newer Dropwizard versions (I am using 0.9.2), you can access the default MetricRegistry
through the setup environment io.dropwizard.setup.Environment
. This default MetricRegistry
already has an InstrumentedResourceMethodApplicationListener
associated with it, which listens to all the metrics of your resources.
If you have registered a resource with the JerseyEnvironment
as under,
environment.jersey().register(resource);
you need only annotate your resource method (or class) with @Timed
, @Metered
or @ExceptionMetered
to register the respective metrics.
@POST
@Timed
public String show() {
return "yay";
}
You can assign a Reporter
(like an Slf4jReporter
or JmxReporter
) to the default MetricRegistry
as under
Slf4jReporter.forRegistry(environment.metrics()).build();
As a quick test to see if your metrics have actually been registered, you can make a GET
call to the URL http://localhost:8081/metrics
or the corresponding Admin Metrics URL in your test environment.
Some other versions require you to explicitly register an InstrumentedResourceMethodApplicationListener
as shown in this Doc