有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Codahale Metrics:在普通Java中使用@Timed Metrics注释

我试图使用codahale度量向普通Java应用程序添加度量。我想使用@Timed注释,但我不清楚它使用哪个MetricRegistry,或者如何告诉它使用哪个MetricRegistry。该应用程序是一个普通的Java8应用程序,使用Maven 3构建,没有Spring,也没有Hibernate

我在dropwizard文档中找不到任何关于如何实现@Timed的文档:https://dropwizard.github.io/metrics/3.1.0/manual/

我添加了以下依赖项:

<dependency>
  <groupId>io.dropwizard.metrics</groupId>
  <artifactId>metrics-core</artifactId>
  <version>3.1.0</version>
</dependency>
<dependency>
  <groupId>com.codahale.metrics</groupId>
  <artifactId>metrics-annotation</artifactId>
  <version>3.0.2</version>
</dependency>

当我使用程序调用计时器时,我可以得到报告,因为我知道使用了哪个MetricsRegistry:

static final MetricRegistry metrics = new MetricRegistry();
private void update() throws SQLException {
  Timer.Context time = metrics.timer("domainobject.update").time();
  try {
    [...]
  } finally {
    time.stop();
  }
}

但是,当我使用更优雅的@Timed注释时,我不知道使用了哪个注册表,因此我无法创建报告器,这意味着我无法报告指标(我甚至不确定这是否真的有任何作用):

@Timed(name = "domainobject.update")
private void update() throws SQLException {
    [...]
}

请就如何在常规Java应用程序中使用@Timed和其他度量标注给出建议

其他信息:我之所以觉得这很奇怪,是因为我添加了Lombok框架,@Slf4j注释确实有效。我在maven pom中添加了Lombok作为依赖项。xml:

<dependency>
  <groupId>org.projectlombok</groupId>
  <artifactId>lombok</artifactId>
  <version>1.14.8</version>
</dependency>

我可以使用@Sl4fj类注释向类中添加一个记录器,而不会弄乱成员变量:

@Slf4j
public class App {
  public void logsome(){
    log.info("Hello there");
  }
}

因此,如果仅仅通过添加一个依赖项就可以做到这一点,我想我只是缺少了一个依赖项或配置,无法让codahale@Timed注释工作,如上所述

(顺便说一句,看看Lombok,它会让你的生活更轻松:http://projectlombok.org/


共 (6) 个答案

  1. # 1 楼答案

    长话短说,如果没有某种AOP(无论是Spring AOP还是AspectJ),就不能使用@Timed

    一两周前,我还决定向我们的项目中添加度量,并选择AspectJ来完成这项任务(主要是因为我在过去出于类似目的使用过它,而且它允许编译时编织,而Spring只允许通过代理运行时)

    你应该可以在这里找到所有必要的信息和说明:https://github.com/astefanutti/metrics-aspectj

    至于Lombok,我猜他们使用内置的javac注释处理器:

    Another point of contention is the implementation of both the code supporting IDE integration as well as the javac annotation processor. Both of these pieces of Project Lombok make use of non-public APIs to accomplish their sorcery. This means that there is a risk that Project Lombok will be broken with subsequent IDE or JDK releases.

  2. # 3 楼答案

    正如另一个答案所述,应用程序中必须有一些东西来监听实例化的类,并检查它们是否有@Timed注释

    如果您使用的是Guice,那么可以使用:https://github.com/palominolabs/metrics-guice

  3. # 4 楼答案

    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();
    }
    
  4. # 5 楼答案

    AOP is overkill and not appropriate for use of @timed, generally speaking.

    默认度量注册表将@timed metrics写入ConcurrentHashMap,并且不附加任何有意义的侦听器

    DropWizard引导构造函数:

    /**
     * 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.

    这里我使用JMX:

    @Override
    public void initialize(Bootstrap<PayloadStorageConfiguration> bootstrap) {
        JmxReporter.forRegistry(bootstrap.getMetricRegistry()).build().start();
    }
    

    这就是你需要做的

    下面是一个输出示例(对Java应用程序/服务器运行jconsole以查看JMX结果):

    enter image description here

  5. # 6 楼答案

    使用@Timed实际上并不需要使用AOP,正如之前在排名靠前的答案中所说的那样,如果您在一个容器中并使用Dropwizard的一个工具库。看球衣2。例如,如果您阅读source,您可以看到x模块使用反射(就像我看到的其他模块一样)

    你可以在the Dropwizard docs中相应的“仪器化___”项目符号下阅读所有这些模块

    我知道OP显然不在这样的容器中工作,但我想提供这些信息,因为我们中的许多人都在寻找这个答案,可能是在一个可以在其运行时环境中注册此类资源的现代web服务上工作