1. Introduction
1.绪论
Monitoring is very helpful for finding bugs and optimizing performance. We could manually instrument our code to add timers and logging, but this would lead to a lot of distracting boilerplate.
监控对于发现错误和优化性能非常有帮助。我们可以手动检测我们的代码以添加定时器和日志,但这将导致大量分散注意力的模板。
On the other hand, we can use a monitoring framework, driven by annotations, such as Dropwizard Metrics.
另一方面,我们可以使用一个监测框架,由注释驱动,例如Dropwizard Metrics。
In this tutorial, we will instrument a simple class using Metrics AspectJ, and the Dropwizard Metrics @Timed annotation.
在本教程中,我们将使用Metrics AspectJ和Dropwizard Metrics @Timed 注解来设计一个简单的类。
2. Maven Setup
2.Maven设置
First of all, let’s add the Metrics AspectJ Maven dependencies to our project:
首先,让我们把Metrics AspectJ的Maven依赖项加入我们的项目。
<dependency>
<groupId>io.astefanutti.metrics.aspectj</groupId>
<artifactId>metrics-aspectj</artifactId>
<version>1.2.0</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.astefanutti.metrics.aspectj</groupId>
<artifactId>metrics-aspectj-deps</artifactId>
<version>1.2.0</version>
</dependency>
We’re using metrics-aspectj to provide metrics via aspect oriented programming, and metrics-aspectj-deps to provide its dependencies.
我们使用metrics-aspectj来通过面向方面的编程提供metrics,以及metrics-aspectj-eps来提供其依赖性。
We also need the aspectj-maven-plugin to set up compile time processing of the metrics annotations:
我们还需要aspectj-maven-plugin来设置编译时对度量注释的处理。
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.8</version>
<configuration>
<complianceLevel>1.8</complianceLevel>
<source>1.8</source>
<target>1.8</target>
<aspectLibraries>
<aspectLibrary>
<groupId>io.astefanutti.metrics.aspectj</groupId>
<artifactId>metrics-aspectj</artifactId>
</aspectLibrary>
</aspectLibraries>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
Now our project is ready to have some Java code instrumented.
现在我们的项目已经准备好了,可以对一些Java代码进行检测。
3. Annotation Instrumentation
3.注释仪器化
Firstly, let’s create a method and annotate it with the @Timed annotation. We’ll also fill the name property with a name for our timer:
首先,让我们创建一个方法,并用@Timed注解来注释它。我们还将在name属性中为我们的定时器填写一个名称。
import com.codahale.metrics.annotation.Timed;
import io.astefanutti.metrics.aspectj.Metrics;
@Metrics(registry = "objectRunnerRegistryName")
public class ObjectRunner {
@Timed(name = "timerName")
public void run() throws InterruptedException {
Thread.sleep(1000L);
}
}
We’re using the @Metrics annotation at the class level to let the Metrics AspectJ framework know this class has methods to be monitored. We’re putting @Timed on the method to create the timer.
我们在类的层面上使用@Metrics注解,让Metrics AspectJ框架知道这个类有需要监控的方法。我们把@Timed放在方法上以创建定时器。
In addition, @Metrics creates a registry using the registry name provided – objectRunnerRegistryName in this case – to store the metrics.
此外, @Metrics 使用提供的注册表名称–本例中为objectRunnerRegistryName–创建一个注册表来存储度量。
Our example code just sleeps for one second to emulate an operation.
我们的示例代码只是睡眠了一秒钟来模拟一个操作。
Now, let’s define a class to start the application and configure our MetricsRegistry:
现在,让我们定义一个类来启动应用程序并配置我们的MetricsRegistry。
public class ApplicationMain {
static final MetricRegistry registry = new MetricRegistry();
public static void main(String args[]) throws InterruptedException {
startReport();
ObjectRunner runner = new ObjectRunner();
for (int i = 0; i < 5; i++) {
runner.run();
}
Thread.sleep(3000L);
}
static void startReport() {
SharedMetricRegistries.add("objectRunnerRegistryName", registry);
ConsoleReporter reporter = ConsoleReporter.forRegistry(registry)
.convertRatesTo(TimeUnit.SECONDS)
.convertDurationsTo(TimeUnit.MILLISECONDS)
.outputTo(new PrintStream(System.out))
.build();
reporter.start(3, TimeUnit.SECONDS);
}
}
In the startReport method of ApplicationMain, we set up the registry instance to the SharedMetricRegistries using the same registry name as used in @Metrics.
在ApplicationMain的startReport方法中,我们将注册表实例设置为SharedMetricRegistries,使用与@Metrics中使用的相同注册表名称。
After that, we create a simple ConsoleReporter to report our metrics from the @Timed annotated method. We should note that there are other types of reporters available.
之后,我们创建一个简单的ConsoleReporter来报告我们来自@Timed注释方法的指标。我们应该注意到,还有其他类型的报告器可用。
Our application will call the timed method five times. Let’s compile it with Maven and then execute it:
我们的应用程序将调用定时方法五次。让我们用Maven编译它,然后执行它。
-- Timers ----------------------------------------------------------------------
ObjectRunner.timerName
count = 5
mean rate = 0.86 calls/second
1-minute rate = 0.80 calls/second
5-minute rate = 0.80 calls/second
15-minute rate = 0.80 calls/second
min = 1000.49 milliseconds
max = 1003.00 milliseconds
mean = 1001.03 milliseconds
stddev = 1.10 milliseconds
median = 1000.54 milliseconds
75% <= 1001.81 milliseconds
95% <= 1003.00 milliseconds
98% <= 1003.00 milliseconds
99% <= 1003.00 milliseconds
99.9% <= 1003.00 milliseconds
As we can see, the Metrics framework provides us with detailed statistics for very little code change to a method we want to instrument.
正如我们所看到的,Metrics框架为我们提供了详细的统计数据,而我们想要检测的方法的代码变化却非常小。
We should note that running the application without the Maven build – for example, through an IDE – might not get the above output. We need to ensure the AspectJ compilation plugin is included in the build for this to work.
我们需要注意的是,在没有Maven构建的情况下运行应用程序–例如通过IDE–可能无法获得上述输出。我们需要确保在构建时包含AspectJ编译插件,这样才能发挥作用。
4. Conclusion
4.总结
In this tutorial, we investigated how to instrument a simple Java application with Metrics AspectJ.
在本教程中,我们研究了如何用Metrics AspectJ对一个简单的Java应用程序进行检测。
We found Metrics AspectJ annotations a good way to instrument code without needing a large application framework like Spring, JEE, or Dropwizard. Instead, by using aspects, we were able to add interceptors at compile-time.
我们发现Metrics AspectJ注解是检测代码的好方法,不需要像Spring、JEE或Dropwizard这样的大型应用框架。相反,通过使用方面,我们能够在编译时添加拦截器。
As always, the complete source code for the example is available over on GitHub.
一如既往,该示例的完整源代码可在GitHub上获得over。