简体   繁体   English

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

[英]Codahale Metrics: using @Timed metrics annotation in plain Java

I am trying to add metrics to a plain Java application using codahale metrics. 我正在尝试使用codahale指标将指标添加到普通Java应用程序。 I'd like to use the @Timed annotation, but it is unclear to me which MetricRegistry it uses, or how to tell it which MetricRegistry to use. 我想使用@Timed注释,但我不清楚它使用哪个MetricRegistry,或者如何告诉它使用哪个MetricRegistry。 The application is a plain Java 8 application, built with Maven 3, no Spring, no Hibernate. 该应用程序是一个普通的Java 8应用程序,使用Maven 3构建,没有Spring,没有Hibernate。

I can not find any documentation on how to implement @Timed in the dropwizard documentation: https://dropwizard.github.io/metrics/3.1.0/manual/ 我在dropwizard文档中找不到有关如何实现@Timed的任何文档: https ://dropwizard.github.io/metrics/3.1.0/manual/

I've added these dependencies: 我添加了这些依赖项:

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

When I use a programatic call to Timer, I can get reports because I know which MetricsRegistry is used: 当我使用对Timer的编程调用时,我可以获得报告,因为我知道使用了哪些MetricsRegistry:

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

But when I use the much more elegant @Timed annotation, I have no idea which registry is used, and therefore I can not create a reporter, which means I can not get the metrics reported (I'm not even sure if this actually does anything): 但是当我使用更优雅的@Timed注释时,我不知道使用了哪个注册表,因此我无法创建一个记者,这意味着我无法报告指标(我甚至不确定这是否确实任何东西):

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

Please advise on how to make the @Timed and other Metrics annotations work in a regular Java application. 请告知如何使@Timed和其他Metrics注释在常规Java应用程序中工作。

Additional info: The reason I am finding this strange is that I have added the Lombok framework and the @Slf4j annotations do work. 附加信息:我发现这个奇怪的原因是我添加了Lombok框架和@ Slf4j注释确实有效。 I added Lombok as a dependency in the maven pom.xml: 我在maven pom.xml中添加了Lombok作为依赖项:

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

And I can use the @Sl4fj class annotation to add a logger to the class without cluttering up the member variables: 我可以使用@ Sl4fj类注释向类中添加一个记录器,而不会使成员变量混乱:

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

So if that's possible by just adding a dependency, I reckon I am just missing a dependency or configuration to get the codahale @Timed annotation work, as described above. 因此,如果只通过添加依赖项就可以实现,我认为我只是缺少一个依赖项或配置来获取codahale @Timed注释工作,如上所述。

(by the way, check out Lombok, it will make your life easier: http://projectlombok.org/ ) (顺便说一句,看看龙目岛,它会让你的生活更轻松: http//projectlombok.org/

Long story short, you cannot use @Timed without some kind of AOP (be it Spring AOP or AspectJ). 长话短说,如果没有某种AOP(无论是Spring AOP还是AspectJ),都不能使用@Timed

A week or two ago, I also decided to add metrics to our project and chose AspectJ for this task (mostly because I used it in the past for similar purpose and because it allows for compile-time weaving while Spring allows only runtime via proxies). 一两个星期前,我还决定为我们的项目添加指标,并选择AspectJ来完成这项任务(主要是因为我过去使用它来达到类似的目的,因为它允许编译时编织,而Spring只允许通过代理运行时) 。

You should be able to find all the necessary information and instructions here: https://github.com/astefanutti/metrics-aspectj . 您应该能够在此处找到所有必要的信息和说明: https//github.com/astefanutti/metrics-aspectj

As for Lombok, I guess they use built-in javac annotations processor: 至于Lombok,我猜他们使用内置的javac注释处理器:

Another point of contention is the implementation of both the code supporting IDE integration as well as the javac annotation processor. 另一个争论点是实现支持IDE集成的代码以及javac注释处理器。 Both of these pieces of Project Lombok make use of non-public APIs to accomplish their sorcery. 这两个项目Lombok都利用非公共API来完成他们的巫术。 This means that there is a risk that Project Lombok will be broken with subsequent IDE or JDK releases. 这意味着使用后续IDE或JDK版本可能会破坏Project Lombok的风险。

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. 如果您在容器内并使用Dropwizard的一个检测库,那么使用@Timed实际上并不需要使用AOP,就像之前在评价最高的答案中所声称的那样。 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 . 例如,请参阅Jersey 2.x模块,如果您阅读了源代码 ,您可以看到它使用反射(就像我看到的其他人一样)。

You can read up on all of these modules in the Dropwizard docs under the corresponding " Instrumenting ____ " bullets. 您可以在相应的“ Instrumenting ____ ”项目符号下的Dropwizard文档中阅读所有这些模块。

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. 我理解OP明确地不在这样的容器中工作,但是我想提供这个信息,因为我们许多寻找这个答案的人可能正在研究一种可以在其运行时环境中注册这些资源的现代Web服务。

Use the built-in MetricRegistry accessed from the bootstrap parameter in the initialize method of your application class. 使用从应用程序类的initialize方法中的bootstrap参数访问的内置MetricRegistry。

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

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. 正如另一个答案所述,你必须在应用程序中有一些东西来监听你的实例化类并检查它们的@Timed注释。

If you're using Guice, you could use: https://github.com/palominolabs/metrics-guice 如果您使用的是Guice,可以使用: https//github.com/palominolabs/metrics-guice

AOP is overkill and not appropriate for use of @timed, generally speaking. 一般而言,AOP过度使用并不适合使用@timed。

The default metrics registry writes @timed metrics to a ConcurrentHashMap and does not attach any meaningful listeners. 默认度量标准注册表将@timed指标写入ConcurrentHashMap,并且不附加任何有意义的侦听器。

DropWizard Bootstrap constructor: DropWizard Bootstrap构造函数:

/**
 * 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: 在这里我使用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): 以下是输出示例(针对Java应用程序/服务器运行jconsole以查看JMX结果):

在此输入图像描述

In newer Dropwizard versions (I am using 0.9.2), you can access the default MetricRegistry through the setup environment io.dropwizard.setup.Environment . 在较新的版本Dropwizard(我使用0.9.2),你可以访问默认MetricRegistry通过设置环境io.dropwizard.setup.Environment This default MetricRegistry already has an InstrumentedResourceMethodApplicationListener associated with it, which listens to all the metrics of your resources. 此默认MetricRegistry已经有一个与之关联的InstrumentedResourceMethodApplicationListener ,它会侦听您资源的所有指标。

If you have registered a resource with the JerseyEnvironment as under, 如果您已将JerseyEnvironment注册为资源,

environment.jersey().register(resource);

you need only annotate your resource method (or class) with @Timed , @Metered or @ExceptionMetered to register the respective metrics. 您只需要使用@Timed@Metered@ExceptionMetered注释您的资源方法(或类)以注册相应的指标。

@POST
@Timed
public String show() {
    return "yay";
}

You can assign a Reporter (like an Slf4jReporter or JmxReporter ) to the default MetricRegistry as under 您可以将Reporter (如Slf4jReporterJmxReporter )分配给默认的MetricRegistry如下所示

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. 作为快速测试以查看您的指标是否实际已注册,您可以在测试环境中对URL http://localhost:8081/metrics或相应的管理指标URL进行GET调用。

Some other versions require you to explicitly register an InstrumentedResourceMethodApplicationListener as shown in this Doc 其他一些版本要求您显式注册InstrumentedResourceMethodApplicationListener ,如本Doc所示

You could also use stagemonitor-core for that. 你也可以使用stagemonitor-core。 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. 优点是stagemonitor(免费和开源btw)不依赖于任何基于容器的AOP,如Spring AOP或EJB拦截器。 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. 它通过运行时附件使用字节码操作,这意味着您甚至不必向应用程序启动添加-javaagent标志 - 普通依赖就足够了。

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. 如果要在Web应用程序或远程EJB应用程序中测量执行时间,则甚至不必手动注释代码。 Also, stagemonitor offers preconfigured Grafana and Kibana dashboards. 此外,stagemonitor还提供预配置的Grafana和Kibana仪表板。

Disclaimer: I'm one of the developers of stagemonitor 免责声明:我是stagemonitor的开发者之一

this simple/right-to-the-point example https://karollotkowski.wordpress.com/2015/10/19/api-endpoint-in-one-minute-with-dropwizard/ just showed it only need the annotation 这个简单/正确的示例https://karollotkowski.wordpress.com/2015/10/19/api-endpoint-in-one-minute-with-dropwizard/只是显示它只需要注释

在此输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 @Timed注释弹簧指标 - @Timed annotation in spring metrics Codahale指标和Dropwizard指标之间的差异 - Difference between Codahale metrics and Dropwizard metrics 如何清除Java codahale Metrics Timers的历史统计数据 - How to clear historical stats from Java codahale Metrics Timers Java / Scala指标 - Codahale - Cluster / Mulitnode和Graphite Reporter - Java/Scala Metrics - Codahale - Cluster/Mulitnode & Graphite Reporter Codahale指标会每天重置并计数 - Codahale metrics counter reset and count everyday yammer &amp; codahale &amp; dropwizard Metrics 之间的差异和关系? - Differences and relationship between yammer & codahale & dropwizard Metrics? codahale指标如何Meter mark()方法线程安全? - How is codahale metrics Meter mark() method threadsafe? Java 错误原因:java.lang.ClassNotFoundException:com.codahale.metrics.JmxReporter - Java Error Caused by: java.lang.ClassNotFoundException: com.codahale.metrics.JmxReporter 线程“main”中的异常 java.lang.NoClassDefFoundError: com/codahale/metrics/Reservoir - Exception in thread "main" java.lang.NoClassDefFoundError: com/codahale/metrics/Reservoir JanusGraph 0.5.2 嵌入式 cassandra java.lang.NoSuchMethodError: com.codahale.metrics.Snapshot - JanusGraph 0.5.2 embedded cassandra java.lang.NoSuchMethodError: com.codahale.metrics.Snapshot
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM