メトリックとAspectJを使用した@TimedAnnotation
1. 序章
モニタリングは、バグの発見とパフォーマンスの最適化に非常に役立ちます。タイマーとロギングを追加するためにコードを手動でインストルメント化することもできますが、これは多くの気が散る定型文につながります。
一方、 DropwizardMetricsなどのアノテーションによって駆動される監視フレームワークを使用できます。
このチュートリアルでは、 Metrics AspectJ と、Dropwizard Metrics @ Timedアノテーションを使用して単純なクラスをインストルメントします。
2. Mavenのセットアップ
まず、MetricsAspectJMavenの依存関係をプロジェクトに追加しましょう。
<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>
アスペクト指向プログラミングを介してmetrics-aspectjを使用してmetricsを提供し、依存関係を提供するためにmetrics-aspectj-depsを使用しています。
メトリックアノテーションのコンパイル時処理を設定するには、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>
これで、プロジェクトでJavaコードをインストルメント化する準備が整いました。
3. アノテーションインストルメンテーション
まず、メソッドを作成し、@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);
}
}
クラスレベルで@Metricsアノテーションを使用して、このクラスに監視対象のメソッドがあることをMetricsAspectJフレームワークに通知しています。 タイマーを作成するためにメソッドに@Timedを配置しています。
さらに、 @Metrics は、提供されたレジストリ名(この場合は objectRunnerRegistryName )を使用してレジストリを作成し、メトリックを格納します。
このサンプルコードは、操作をエミュレートするために1秒間スリープします。
それでは、アプリケーションを起動して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);
}
}
ApplicationMainのstartReportメソッドでは、 @Metrics で使用されているのと同じレジストリ名を使用して、SharedMetricRegistriesにレジストリインスタンスを設定します。 。
その後、単純な ConsoleReporter を作成して、@Timed注釈付きメソッドからメトリックをレポートします。 他のタイプのレポーターが利用可能であることに注意する必要があります。
このアプリケーションは、timedメソッドを5回呼び出します。 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
ご覧のとおり、メトリクスフレームワークは、インストルメントするメソッドへのコード変更がほとんどない場合の詳細な統計を提供します。
Mavenビルドなしで(たとえば、IDEを介して)アプリケーションを実行すると、上記の出力が得られない場合があることに注意してください。 これを機能させるには、AspectJコンパイルプラグインがビルドに含まれていることを確認する必要があります。
4. 結論
このチュートリアルでは、MetricsAspectJを使用して単純なJavaアプリケーションをインストルメント化する方法を調査しました。
Metrics AspectJアノテーションは、Spring、JEE、Dropwizardなどの大規模なアプリケーションフレームワークを必要とせずにコードをインストルメント化するための優れた方法であることがわかりました。 代わりに、アスペクトを使用することで、コンパイル時にインターセプターを追加することができました。
いつものように、この例の完全なソースコードは、GitHubでから入手できます。