Codahale Metrics: using @Timed metrics annotation in plain Java

后端 未结 8 927
南方客
南方客 2020-12-29 03:18

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,

相关标签:
8条回答
  • 2020-12-29 03:33

    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

    0 讨论(0)
  • 2020-12-29 03:35

    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();
    }
    
    0 讨论(0)
  • 2020-12-29 03:35

    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):

    0 讨论(0)
  • 2020-12-29 03:40

    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

    0 讨论(0)
  • 2020-12-29 03:47

    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.

    0 讨论(0)
  • 2020-12-29 03:51

    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

    0 讨论(0)
提交回复
热议问题