web-dev-qa-db-ja.com

Codahaleメトリクス:@TimedメトリクスアノテーションをプレーンJavaで使用する

Codahaleメトリックを使用して、プレーンJavaアプリケーションにメトリックを追加しようとしています。@ Timedアノテーションを使用したいのですが、どのMetricRegistryを使用するか、またはどのように伝えるかがわかりませんアプリケーションは、Maven 3、Spring、Hibernateを使用せずに構築されたプレーンなJava 8アプリケーションです。

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>

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();
  }
}

しかし、はるかにエレガントな@Timedアノテーションを使用すると、どのレジストリが使用されるのかわからないため、レポーターを作成できません。つまり、メトリックがレポートされないことを意味します(これが実際に行われるかどうかはわかりません)何でも):

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

通常のJavaアプリケーションで@Timedおよびその他のメトリックアノテーションを機能させる方法についてアドバイスしてください。

追加情報:この奇妙なことに気づいたのは、Lombokフレームワークを追加し、@ Slf4jアノテーションが機能するからです。 Lombokをmaven pom.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/

35
Rolf

簡単に言えば、@TimedはAOP(Spring AOPでもAspectJでも)なしでは使用できません。

1、2週間前、プロジェクトにメトリックを追加し、このタスクにAspectJを選択することも決定しました(主に過去に同様の目的で使用し、Springはプロキシ経由のランタイムのみを許可するのに対し、コンパイル時のウィービングを許可するため) 。

ここで必要な情報と手順をすべて見つけることができるはずです: https://github.com/astefanutti/metrics-aspectj

Lombokに関しては、組み込みのjavac注釈プロセッサを使用していると思います。

競合のもう1つのポイントは、IDE統合をサポートするコードとjavac注釈プロセッサの両方の実装です。ProjectLombokのこれらの部分はどちらも、ソーサリーを達成するために非公開APIを使用します。これは、Project Lombokが後続のIDEまたはJDKリリースで破損するリスクがあることを意味します。

17
Andrew Logvinov

@Timedの使用は、コンテナ内でDropwizardのインストルメンテーションライブラリの1つを使用している場合、以前は一流の回答で主張されていたように、AOPの使用を実際に必要としません。たとえば、Jersey 2.xモジュールを参照してください。 source を読むと、リフレクションが使用されていることがわかります(他の人が見たように)。

Dropwizard docs の対応する「Instrumenting ____」の箇条書きの下で、これらのモジュールのすべてを参照できます。

私はOPがそのようなコンテナ内で明示的に動作していないことを理解していますが、この答えを探している私たちの多くはそのようなリソースをランタイム環境に登録できる最新のWebサービスで動作している可能性があるため、この情報を提供したいと思いました。

12

アプリケーションクラスのinitializeメソッドのbootstrapパラメーターからアクセスされる組み込みのMetricRegistryを使用します。

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

AOPは過剰であり、一般的に言えば@timedの使用には適していません。

デフォルトのメトリックレジストリは、@ timedメトリックをConcurrentHashMapに書き込み、意味のあるリスナーをアタッチしません。

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>();
}

したがって、結果を表示するには、適切なメトリックレジストリを構築/開始/登録する必要があります。

ここでは、JMXを使用します。

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

あなたがする必要があるのはそれだけです。

出力の例は次のとおりです(Java application/serverに対してjconsoleを実行してJMXの結果を表示します):

enter image description here

3

他の答えが述べたように、インスタンス化されたクラスをリッスンし、@ Timedアノテーションがあるかどうかをチェックするには、アプリケーションに何かが必要です。

Guiceを使用している場合は、次を使用できます。 https://github.com/palominolabs/metrics-guice

3
woxwoxwoxwox

新しいDropwizardバージョン(0.9.2を使用しています)では、セットアップ環境io.dropwizard.setup.Environmentを介してデフォルトのMetricRegistryにアクセスできます。このデフォルトのMetricRegistryには既にInstrumentedResourceMethodApplicationListenerが関連付けられており、リソースのすべてのメトリックをリッスンします。

下のようにJerseyEnvironmentを使用してリソースを登録した場合、

environment.jersey().register(resource);

リソースメソッド(またはクラス)に@Timed@Metered、または@ExceptionMeteredの注釈を付けるだけで、それぞれのメトリックを登録できます。

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

ReporterSlf4jReporterJmxReporterなど)をデフォルトのMetricRegistryに割り当てることができます

Slf4jReporter.forRegistry(environment.metrics()).build();

メトリックが実際に登録されているかどうかを確認する簡単なテストとして、テスト環境でURL http://localhost:8081/metricsまたは対応する管理メトリックURLにGET呼び出しを行うことができます。

他のバージョンでは、示されているようにInstrumentedResourceMethodApplicationListenerを明示的に登録する必要があります このドキュメント内

1
Faraz

そのためにstagemonitor-coreを使用することもできます。ドキュメンテーション here および here を参照してください。利点は、stagemonitor(これは無料でオープンソースである)が、Spring AOPやEJBインターセプターなどのコンテナーベースのAOPに依存しないことです。ランタイムアタッチメントによるバイトコード操作を使用します。つまり、アプリケーションの起動に-javaagentフラグを追加する必要さえありません-単純な依存関係で十分です。

WebアプリケーションまたはリモートEJBアプリケーションで実行時間を測定する場合は、コードに手動で注釈を付ける必要さえありません。また、stagemonitorは事前設定されたGrafanaおよびKibanaダッシュボードを提供します。

免責事項:私はstagemonitorの開発者の一人です

0
Felix

この単純な/右から右への例 https://karollotkowski.wordpress.com/2015/10/19/api-endpoint-in-one-minute-with-dropwizard/ ちょうど示しました注釈のみが必要です

enter image description here

0
gli00001