これはそのままでは機能しません。質問を検索したところ、 Codahale Metrics:プレーンJavaで@Timedメトリックアノテーションを使用 これが機能する唯一の方法はaspectjを使用することであると述べられていました。これをプロジェクトに追加しましたが、MetricRegistryにメトリックが表示されません。
これは私のpomファイルです。 com.codahale.metrics:metrics-annotation
にロードするlibratoライブラリを追加しました。
<dependency>
<groupId>io.astefanutti.metrics.aspectj</groupId>
<artifactId>metrics-aspectj</artifactId>
<version>${metrics-aspectj.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.10</version>
</dependency>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.7</version>
<configuration>
<showWeaveInfo>true</showWeaveInfo>
<source>1.8</source>
<target>1.8</target>
<complianceLevel>1.8</complianceLevel>
<encoding>UTF-8</encoding>
<verbose>true</verbose>
<aspectLibraries>
<aspectLibrary>
<groupId>io.astefanutti.metrics.aspectj</groupId>
<artifactId>metrics-aspectj</artifactId>
</aspectLibrary>
</aspectLibraries>
</configuration>
<executions>
<execution>
<phase>process-sources</phase>
<goals>
<goal>compile</goal>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
</plugin>
<dependency>
<groupId>com.librato.metrics</groupId>
<artifactId>metrics-librato</artifactId>
<version>${metrics-librato.version}</version>
</dependency>
これは私がメトリックを使用しようとしている方法です
@Metrics(registry = "default") // this.metricRegistry is default
public class Foo {
@Inject
private MetricRegistry metricRegistry;
...
@Metered(name = "meterName")
public void bar() {
Meter meter = metricRegistry.meter("manual");
meter.mark();
// this.metricRegistry does not contain "meterName" after the ConsoleReporter prints the metrics for "default"
// this.metricRegistry contains "manual" after the ConsoleReporter prints the metrics for "default"
}
コンパイルすると、ログにこれが表示されます。
[INFO] Extending interface set for type 'Foo' (Foo.Java) to include 'io.astefanutti.metrics.aspectj.Profiled' (MetricAspect.aj)
[INFO] Type 'Foo' (Foo.Java) has intertyped field from 'io.astefanutti.metrics.aspectj.MetricAspect' (MetricAspect.aj:'Java.util.Map<Java.lang.String,io.astefanutti.metrics.aspectj.AnnotatedMetric<com.codahale.metrics.Gauge>> io.astefanutti.metrics.aspectj.Profiled.gauges')
[INFO] Type 'Foo' (Foo.Java) has intertyped field from 'io.astefanutti.metrics.aspectj.MetricAspect' (MetricAspect.aj:'Java.util.Map<Java.lang.String,io.astefanutti.metrics.aspectj.AnnotatedMetric<com.codahale.metrics.Meter>> io.astefanutti.metrics.aspectj.Profiled.meters')
[INFO] Type 'Foo' (Foo.Java) has intertyped field from 'io.astefanutti.metrics.aspectj.MetricAspect' (MetricAspect.aj:'Java.util.Map<Java.lang.String,io.astefanutti.metrics.aspectj.AnnotatedMetric<com.codahale.metrics.Timer>> io.astefanutti.metrics.aspectj.Profiled.timers')
[INFO] Join point 'staticinitialization(void Foo.<clinit>())' in Type 'Foo' (Foo.Java:46) advised by after advice from 'io.astefanutti.metrics.aspectj.MetricStaticAspect' (metrics-aspectj-1.2.0.jar!MetricStaticAspect.class:41(from MetricStaticAspect.aj))
[INFO] Join point 'method-execution(void Foo.bar())' in Type 'Foo' (Foo.Java:74) advised by around advice from 'io.astefanutti.metrics.aspectj.TimedAspect' (metrics-aspectj-1.2.0.jar!TimedAspect.class:26(from TimedAspect.aj))
[INFO] Join point 'method-execution(void Foo.bar())' in Type 'Foo' (Foo.Java:74) advised by before advice from 'io.astefanutti.metrics.aspectj.MeteredAspect' (metrics-aspectj-1.2.0.jar!MeteredAspect.class:26(from MeteredAspect.aj))
設定した注釈付きメトリックが正しく機能していることを示しているようです。ただし、これはログにも表示されます
[WARNING] advice defined in io.astefanutti.metrics.aspectj.TimedStaticAspect has not been applied [Xlint:adviceDidNotMatch]
/Users/x/.m2/repository/io/astefanutti/metrics/aspectj/metrics-aspectj/1.2.0/metrics-aspectj-1.2.0.jar!io/astefanutti/metrics/aspectj/TimedStaticAspect.class:26
[WARNING] advice defined in io.astefanutti.metrics.aspectj.ExceptionMeteredAspect has not been applied [Xlint:adviceDidNotMatch]
/Users/x/.m2/repository/io/astefanutti/metrics/aspectj/metrics-aspectj/1.2.0/metrics-aspectj-1.2.0.jar!io/astefanutti/metrics/aspectj/ExceptionMeteredAspect.class:26
[WARNING] advice defined in io.astefanutti.metrics.aspectj.ExceptionMeteredStaticAspect has not been applied [Xlint:adviceDidNotMatch]
/Users/x/.m2/repository/io/astefanutti/metrics/aspectj/metrics-aspectj/1.2.0/metrics-aspectj-1.2.0.jar!io/astefanutti/metrics/aspectj/ExceptionMeteredStaticAspect.class:26
[WARNING] advice defined in io.astefanutti.metrics.aspectj.MeteredStaticAspect has not been applied [Xlint:adviceDidNotMatch]
/Users/x/.m2/repository/io/astefanutti/metrics/aspectj/metrics-aspectj/1.2.0/metrics-aspectj-1.2.0.jar!io/astefanutti/metrics/aspectj/MeteredStaticAspect.class:26
[WARNING] advice defined in io.astefanutti.metrics.aspectj.TimedAspect has not been applied [Xlint:adviceDidNotMatch]
/Users/x/.m2/repository/io/astefanutti/metrics/aspectj/metrics-aspectj/1.2.0/metrics-aspectj-1.2.0.jar!io/astefanutti/metrics/aspectj/TimedAspect.class:26
[WARNING] advice defined in io.astefanutti.metrics.aspectj.TimedStaticAspect has not been applied [Xlint:adviceDidNotMatch]
/Users/x/.m2/repository/io/astefanutti/metrics/aspectj/metrics-aspectj/1.2.0/metrics-aspectj-1.2.0.jar!io/astefanutti/metrics/aspectj/TimedStaticAspect.class:26
[WARNING] advice defined in io.astefanutti.metrics.aspectj.MetricAspect has not been applied [Xlint:adviceDidNotMatch]
/Users/x/.m2/repository/io/astefanutti/metrics/aspectj/metrics-aspectj/1.2.0/metrics-aspectj-1.2.0.jar!io/astefanutti/metrics/aspectj/MetricAspect.class:45
[WARNING] advice defined in io.astefanutti.metrics.aspectj.ExceptionMeteredAspect has not been applied [Xlint:adviceDidNotMatch]
/Users/x/.m2/repository/io/astefanutti/metrics/aspectj/metrics-aspectj/1.2.0/metrics-aspectj-1.2.0.jar!io/astefanutti/metrics/aspectj/ExceptionMeteredAspect.class:26
[WARNING] advice defined in io.astefanutti.metrics.aspectj.MeteredAspect has not been applied [Xlint:adviceDidNotMatch]
/Users/x/.m2/repository/io/astefanutti/metrics/aspectj/metrics-aspectj/1.2.0/metrics-aspectj-1.2.0.jar!io/astefanutti/metrics/aspectj/MeteredAspect.class:26
[WARNING] advice defined in io.astefanutti.metrics.aspectj.ExceptionMeteredStaticAspect has not been applied [Xlint:adviceDidNotMatch]
/Users/x/.m2/repository/io/astefanutti/metrics/aspectj/metrics-aspectj/1.2.0/metrics-aspectj-1.2.0.jar!io/astefanutti/metrics/aspectj/ExceptionMeteredStaticAspect.class:26
[WARNING] advice defined in io.astefanutti.metrics.aspectj.MetricStaticAspect has not been applied [Xlint:adviceDidNotMatch]
/Users/x/.m2/repository/io/astefanutti/metrics/aspectj/metrics-aspectj/1.2.0/metrics-aspectj-1.2.0.jar!io/astefanutti/metrics/aspectj/MetricStaticAspect.class:41
[WARNING] advice defined in io.astefanutti.metrics.aspectj.MeteredStaticAspect has not been applied [Xlint:adviceDidNotMatch]
/Users/x/.m2/repository/io/astefanutti/metrics/aspectj/metrics-aspectj/1.2.0/metrics-aspectj-1.2.0.jar!io/astefanutti/metrics/aspectj/MeteredStaticAspect.class:26
これが私のアプリのセットアップです
@Override
public void run(AppConfiguration configuration, Environment environment) {
ConsoleReporter reporter = ConsoleReporter.forRegistry(environment.metrics())
.convertRatesTo(TimeUnit.SECONDS)
.convertDurationsTo(TimeUnit.MILLISECONDS)
.build();
reporter.start(2, TimeUnit.MINUTES);
}
私はこれを試してみましたが、うまくいきました。これが私のセットアップ全体です:
pom.xml:
_<project xmlns="http://maven.Apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.Apache.org/POM/4.0.0 http://maven.Apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>my-app</name>
<url>http://maven.Apache.org</url>
<dependencies>
<dependency>
<groupId>io.astefanutti.metrics.aspectj</groupId>
<artifactId>metrics-aspectj</artifactId>
<version>1.2.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<configuration>
<aspectLibraries>
<aspectLibrary>
<groupId>io.astefanutti.metrics.aspectj</groupId>
<artifactId>metrics-aspectj</artifactId>
</aspectLibrary>
</aspectLibraries>
<complianceLevel>1.8</complianceLevel>
<source>1.8</source>
<target>1.8</target>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.Apache.maven.plugins</groupId>
<artifactId>maven-Assembly-plugin</artifactId>
<version>2.4.1</version>
<configuration>
<!-- get all project dependencies -->
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<!-- MainClass in mainfest make a executable jar -->
<archive>
<manifest>
<mainClass>com.mkyong.core.utils.App</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-Assembly</id>
<!-- bind to the packaging phase -->
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
_
_aspectj-maven-plugin
_を追加する必要があることに注意してください。後でテストするためにAssembly
プラグインも追加しています。これは実際には必要ありません。ローカルボックスへの依存関係を探しに行きたくありませんでした。
私の時限クラス:
_package com.mycompany.app;
import Java.util.concurrent.ThreadLocalRandom;
import com.codahale.metrics.annotation.Timed;
import io.astefanutti.metrics.aspectj.Metrics;
@Metrics(registry = "someMetrics")
public class TimedClass {
@Timed(name = "test")
public void doSomething() {
try {
Thread.sleep(200L);
} catch (InterruptedException e) {
}
System.out.println("Done");
}
@Timed(name = "test-random")
public void doSomething2() {
try {
Thread.sleep(ThreadLocalRandom.current().nextLong(100L));
} catch (InterruptedException e) {
}
System.out.println("Done");
}
}
_
そしてアプリ:
_package com.mycompany.app;
import Java.util.concurrent.TimeUnit;
import com.codahale.metrics.ConsoleReporter;
import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.SharedMetricRegistries;
public class App {
public static void main(String[] args) throws InterruptedException {
MetricRegistry metrics =
SharedMetricRegistries.getOrCreate("someMetrics");
ConsoleReporter.forRegistry(metrics)
.convertRatesTo(TimeUnit.SECONDS)
.convertDurationsTo(TimeUnit.MILLISECONDS)
.build()
.start(1, TimeUnit.SECONDS);
TimedClass c = new TimedClass();
for(int i = 0; i < 10; i++) {
c.doSomething();
c.doSomething2();
}
c.doSomething();
Thread.sleep(1010L);
}
}
_
ここで何が起こるかというと、compilingの間、アスペクトのMavenプラグインは、使用するアノテーションを見つけてアスペクトを適用します。
あなたの場合(そして私の場合)、例えばこれはメトリクスアスペクトのソースからのものです:
_final aspect TimedAspect {
pointcut timed(Profiled object) : execution(@Timed !static * (@Metrics Profiled+).*(..)) && this(object);
Object around(Profiled object) : timed(object) {
String methodSignature = ((MethodSignature) thisJoinPointStaticPart.getSignature()).getMethod().toString();
Timer timer = object.timers.get(methodSignature).getMetric();
Timer.Context context = timer.time();
try {
return proceed(object);
} finally {
context.stop();
}
}
}
_
上記のすべては言うことです:
静的ではなく、_@Timed
_アノテーションが付いているメソッドは、「around」メソッド内で実行する必要があります。
これで、次のようにしてコンパイルしてパッケージ化できます。
_mvn clean install package
_
これにより、適用されていない側面に対して一連の警告が出力されますが、それはまったく問題ありません(実際には使用していません)。
さらに、これでアプリケーションを含むfat-jarができました。これを実行して、実行した内容が機能するかどうかを確認できます。
_Java -cp target/my-app-1.0-SNAPSHOT-jar-with-dependencies.jar com.mycompany.app.App
_
印刷されます:
_artur@pdb-ct ~/dev/repo/my-app $ Java -cp target/my-app-1.0-SNAPSHOT-jar-with-dependencies.jar com.mycompany.app.App
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Done
Done
Done
Done
Done
Done
Done
Done
04/01/18 15:10:42 ==============================================================
-- Timers ----------------------------------------------------------------------
com.mycompany.app.TimedClass.test
count = 4
mean rate = 4.11 calls/second
1-minute rate = 0.00 calls/second
5-minute rate = 0.00 calls/second
15-minute rate = 0.00 calls/second
min = 200.21 milliseconds
max = 200.37 milliseconds
mean = 200.29 milliseconds
stddev = 0.06 milliseconds
median = 200.25 milliseconds
75% <= 200.32 milliseconds
95% <= 200.37 milliseconds
98% <= 200.37 milliseconds
99% <= 200.37 milliseconds
99.9% <= 200.37 milliseconds
com.mycompany.app.TimedClass.test-random
count = 4
mean rate = 4.10 calls/second
1-minute rate = 0.00 calls/second
5-minute rate = 0.00 calls/second
15-minute rate = 0.00 calls/second
min = 20.41 milliseconds
max = 32.28 milliseconds
mean = 26.07 milliseconds
stddev = 4.56 milliseconds
median = 28.26 milliseconds
75% <= 32.28 milliseconds
95% <= 32.28 milliseconds
98% <= 32.28 milliseconds
99% <= 32.28 milliseconds
99.9% <= 32.28 milliseconds
Done
Done
Done
Done
Done
Done
Done
04/01/18 15:10:43 ==============================================================
-- Timers ----------------------------------------------------------------------
com.mycompany.app.TimedClass.test
count = 8
mean rate = 4.06 calls/second
1-minute rate = 0.00 calls/second
5-minute rate = 0.00 calls/second
15-minute rate = 0.00 calls/second
min = 200.16 milliseconds
max = 200.37 milliseconds
mean = 200.25 milliseconds
stddev = 0.06 milliseconds
median = 200.25 milliseconds
75% <= 200.26 milliseconds
95% <= 200.37 milliseconds
98% <= 200.37 milliseconds
99% <= 200.37 milliseconds
99.9% <= 200.37 milliseconds
com.mycompany.app.TimedClass.test-random
count = 7
mean rate = 3.55 calls/second
1-minute rate = 0.00 calls/second
5-minute rate = 0.00 calls/second
15-minute rate = 0.00 calls/second
min = 20.41 milliseconds
max = 97.20 milliseconds
mean = 43.68 milliseconds
stddev = 28.17 milliseconds
median = 28.26 milliseconds
75% <= 76.30 milliseconds
95% <= 97.20 milliseconds
98% <= 97.20 milliseconds
99% <= 97.20 milliseconds
99.9% <= 97.20 milliseconds
Done
Done
Done
Done
Done
Done
04/01/18 15:10:44 ==============================================================
-- Timers ----------------------------------------------------------------------
com.mycompany.app.TimedClass.test
count = 11
mean rate = 3.70 calls/second
1-minute rate = 0.00 calls/second
5-minute rate = 0.00 calls/second
15-minute rate = 0.00 calls/second
min = 200.13 milliseconds
max = 200.37 milliseconds
mean = 200.23 milliseconds
stddev = 0.07 milliseconds
median = 200.21 milliseconds
75% <= 200.26 milliseconds
95% <= 200.37 milliseconds
98% <= 200.37 milliseconds
99% <= 200.37 milliseconds
99.9% <= 200.37 milliseconds
com.mycompany.app.TimedClass.test-random
count = 10
mean rate = 3.37 calls/second
1-minute rate = 0.00 calls/second
5-minute rate = 0.00 calls/second
15-minute rate = 0.00 calls/second
min = 15.19 milliseconds
max = 97.20 milliseconds
mean = 48.90 milliseconds
stddev = 30.99 milliseconds
median = 32.28 milliseconds
75% <= 76.30 milliseconds
95% <= 97.20 milliseconds
98% <= 97.20 milliseconds
99% <= 97.20 milliseconds
99.9% <= 97.20 milliseconds
_
いくつかのポイント:
これは、Eclipse内では機能しません。それを機能させるには、拡張機能をインストールする必要があります(私はそれを試していません)。ここを参照してください:
https://github.com/astefanutti/metrics-aspectj/blob/master/README.md
また、AJDTの使用方法については:
https://www.ibm.com/developerworks/library/j-ajdt/
その理由は(私はこれにあまり時間をかけていなかったので曖昧です)、アスペクトは実行時ではなくコンパイル時に適用されるからです。 EclipseはIDE内で実行されるときに独自のコンパイラーを使用するため、コードを実行するだけです。ただし、pomファイル内のmavenプラグインは、コードをコンパイルするときにアスペクトを適用するものです。
それがお役に立てば幸いです、
P.S.ネーミング/パッケージングを許してください-デフォルトのMavenジェネレーターを使用しました
--Artur
ファローアップ:
上記のソリューションを使用する場合は、dropwizardメトリックを共有メトリックに追加するだけです。例えば:
_ MetricRegistry myCustomRegistry = new MetricRegistry();
SharedMetricRegistries.add("my-metric-registry", myCustomRegistry);
_
あなたの場合、これはenvironment().metrics()
または同様のものから来ます。
あなたが直面している問題は、AspectJアドバイスで使用されているMetricRegistry
インスタンスが、手動の計測テストやConsoleReporter
で使用しているインスタンスとは異なることです。
あなたの質問は_@Inject
_- ed MetricRegistry
インスタンスがどこから来たのかを特定していないので、それはあなたがConsoleReporter
で使用しているのと同じインスタンスであると推測することしかできませんが、それはおそらく、AspectJアドバイスで使用される_"default"
_レジストリとは異なるインスタンス。 AspectJのアドバイスで使用されるものは
_SharedMetricRegistries.getOrCreate("default");
_
あなたの問題を解決するために、あなたはすべきですどちらか:
_@Inject
_- ed MetricRegistry
インスタンスとenvironment.metrics()
によって返されるインスタンスがSharedMetricRegistries.getOrCreate("default")
と同じであることを確認します。これには、好みの依存性注入フレームワークの方法を使用します。ファクトリメソッドを使用する方法(Springの場合は_@Bean
_、CDIの場合は_@Produces
_)。
Foo
クラス_@Metrics
_アノテーションのregistry
値で次のようにEL式を使用します。
_@Metrics(registry = "${this.metricRegistry}")
_
上記の参照されたmetricRegistry
プロパティのゲッターを提供します。
_public MetricRegistry getMetricRegistry() {
return this.metricRegistry;
}
_
プロジェクトに必要なELライブラリがあることを確認してください。
_<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.el</artifactId>
<version>3.0.1-b09</version>
</dependency>
_