Dropwizardメトリックの紹介

1前書き

Metrics は、Javaアプリケーション用の計測器を提供するJavaライブラリです。

これにはいくつかのモジュールがあります。この記事では、metrics-coreモジュール、metrics-healthchecksモジュール、metrics-servletsモジュール、およびmetrics-servletモジュールを詳しく説明し、残りの部分については参考のためにスケッチします。

2モジュール metrics-core

2.1. Mavenの依存関係

metrics-core モジュールを使用するには、 pom.xml ファイルに追加する必要がある依存関係が1つだけ必要です。

<dependency>
    <groupId>io.dropwizard.metrics</groupId>
    <artifactId>metrics-core</artifactId>
    <version>3.1.2</version>
</dependency>

そして、あなたはその最新版を見つけることができますhttps://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22io.dropwizard.metrics%22%20AND%20a%3A%22metrics-core%22[ここに]。

2.2. MetricRegistry

簡単に言うと、 MetricRegistry クラスを使用して1つ以上のメトリクスを登録します。

すべての測定基準に対して1つの測定基準レジストリを使用できますが、測定基準ごとに異なるレポート方法を使用する場合は、測定基準をグループに分割し、グループごとに異なる測定基準レジストリを使用することもできます。

今すぐ MetricRegistry を作成しましょう:

MetricRegistry metricRegistry = new MetricRegistry();

そして、この MetricRegistry にいくつかのメトリックを登録できます。

Meter meter1 = new Meter();
metricRegistry.register("meter1", meter1);

Meter meter2 = metricRegistry.meter("meter2");

新しいメトリックを作成するには、2つの基本的な方法があります。1つを自分でインスタンス化すること、または1つをメトリックレジストリから取得することです。ご覧のとおり、上記の例では両方を使用し、 Meter オブジェクト "meter1"をインスタンス化しています。また、 metricRegistry によって作成される別の Meter オブジェクト "meter2"を取得しています。

メトリックレジストリでは、上記のメトリック名として「meter1」と「meter2」を使用したため、すべてのメトリックには一意の名前があります。 MetricRegistry は、適切なメトリック名を作成するのに役立つ一連の静的ヘルパーメソッドも提供します。

String name1 = MetricRegistry.name(Filter.class, "request", "count");
String name2 = MetricRegistry.name("CustomFilter", "response", "count");

一連のメトリックレジストリを管理する必要がある場合は、 SharedMetricRegistries クラスを使用できます。これはシングルトンでスレッドセーフです。そこにメトリックレジスタを追加し、そこからこのメトリックレジスタを取り出し、それを削除することができます。

SharedMetricRegistries.add("default", metricRegistry);
MetricRegistry retrievedMetricRegistry = SharedMetricRegistries.getOrCreate("default");
SharedMetricRegistries.remove("default");

** 3メトリクスの概念

**

metrics-coreモジュールは、いくつかの一般的に使用される測定基準タイプを提供します。

メトリックの値を出力する Meter Gauge Counter Histogram 、および Timer 、および Reporter

3.1. メーター

Meter は、イベント発生数と発生率を測定します。

Meter meter = new Meter();
long initCount = meter.getCount();
assertThat(initCount, equalTo(0L));

meter.mark();
assertThat(meter.getCount(), equalTo(1L));

meter.mark(20);
assertThat(meter.getCount(), equalTo(21L));

double meanRate = meter.getMeanRate();
double oneMinRate = meter.getOneMinuteRate();
double fiveMinRate = meter.getFiveMinuteRate();
double fifteenMinRate = meter.getFifteenMinuteRate();

getCount() メソッドはイベント発生数を返し、 mark() メソッドはイベント発生数に1またはnを加算します。 Meter オブジェクトは、最近の1分間、最近の5分間、および最近の四半期の、それぞれのMeterライフタイム全体の平均レートを表す4つのレートを提供します。

3.2. ゲージ

Gauge は、単に特定の値を返すために使用されるインタフェースです。 metrics-coreモジュールはそれのいくつかの実装を提供します。

RatioGauge 、http://metrics.dropwizard.io/3.1.0/apidocs/com/codahale/metrics/annotation/CachedGauge.html[ CachedGauge ]、http://metrics.dropwizard.io/3.1.0/apidocs/com/codahale/metrics/DerivativeGauge.html[ DerivativeGauge ]およびhttp://metrics.dropwizard.io/3.1 .0/apidocs/com/codahale/metrics/JmxAttributeGauge.html[ JmxAttributeGauge ]。

RatioGauge は抽象クラスで、ある値と別の値の比率を測定します。

使い方を見てみましょう。まず、クラス AttendanceRatioGauge を実装します。

public class AttendanceRatioGauge extends RatioGauge {
    private int attendanceCount;
    private int courseCount;

    @Override
    protected Ratio getRatio() {
        return Ratio.of(attendanceCount, courseCount);
    }

   //standard constructors
}

そしてそれをテストします。

RatioGauge ratioGauge = new AttendanceRatioGauge(15, 20);

assertThat(ratioGauge.getValue(), equalTo(0.75));

CachedGauge は、値をキャッシュできるもう1つの抽象クラスです。そのため、値の計算に費用がかかる場合に非常に役立ちます。それを使うには、 ActiveUsersGauge クラスを実装する必要があります。

public class ActiveUsersGauge extends CachedGauge<List<Long>> {

    @Override
    protected List<Long> loadValue() {
        return getActiveUserCount();
    }

    private List<Long> getActiveUserCount() {
        List<Long> result = new ArrayList<Long>();
        result.add(12L);
        return result;
    }

   //standard constructors
}

それからそれが期待通りに動くかどうか確かめるためにそれをテストします。

Gauge<List<Long>> activeUsersGauge = new ActiveUsersGauge(15, TimeUnit.MINUTES);
List<Long> expected = new ArrayList<>();
expected.add(12L);

assertThat(activeUsersGauge.getValue(), equalTo(expected));

ActiveUsersGauge をインスタンス化するときに、キャッシュの有効期限を15分に設定しました。

DerivativeGauge も抽象クラスであり、その値として他の Gauge から値を派生させることができます。

例を見てみましょう。

public class ActiveUserCountGauge extends DerivativeGauge<List<Long>, Integer> {

    @Override
    protected Integer transform(List<Long> value) {
        return value.size();
    }

   //standard constructors
}

この Gauge は、その値を ActiveUsersGauge から派生しているので、基本リストのサイズからの値になるはずです。

Gauge<List<Long>> activeUsersGauge = new ActiveUsersGauge(15, TimeUnit.MINUTES);
Gauge<Integer> activeUserCountGauge = new ActiveUserCountGauge(activeUsersGauge);

assertThat(activeUserCountGauge.getValue(), equalTo(1));

JmxAttributeGauge は、JMXを介して公開されている他のライブラリの指標にアクセスする必要がある場合に使用されます。

3.3. カウンタ

Counter は、増分と減分を記録するために使用されます。

Counter counter = new Counter();
long initCount = counter.getCount();
assertThat(initCount, equalTo(0L));

counter.inc();
assertThat(counter.getCount(), equalTo(1L));

counter.inc(11);
assertThat(counter.getCount(), equalTo(12L));

counter.dec();
assertThat(counter.getCount(), equalTo(11L));

counter.dec(6);
assertThat(counter.getCount(), equalTo(5L));

3.4. ヒストグラム

Histogram Long 値のストリームを追跡するために使用され、__max、min、平均、中央値、標準偏差、75パーセンタイルなどの統計的特性を分析します。

Histogram histogram = new Histogram(new UniformReservoir());
histogram.update(5);
long count1 = histogram.getCount();
assertThat(count1, equalTo(1L));

Snapshot snapshot1 = histogram.getSnapshot();
assertThat(snapshot1.getValues().length, equalTo(1));
assertThat(snapshot1.getValues()[0], equalTo(5L));

histogram.update(20);
long count2 = histogram.getCount();
assertThat(count2, equalTo(2L));

Snapshot snapshot2 = histogram.getSnapshot();
assertThat(snapshot2.getValues().length, equalTo(2));
assertThat(snapshot2.getValues()[1], equalTo(20L));
assertThat(snapshot2.getMax(), equalTo(20L));
assertThat(snapshot2.getMean(), equalTo(12.5));
assertEquals(10.6, snapshot2.getStdDev(), 0.1);
assertThat(snapshot2.get75thPercentile(), equalTo(20.0));
assertThat(snapshot2.get999thPercentile(), equalTo(20.0));

ヒストグラムはリザーバーサンプリングを使用してデータをサンプリングし、ヒストグラムオブジェクトをインスタンス化するときは、明示的にそのリザーバーを設定する必要があります。

Reservoir はインターフェースであり、metrics-coreはそれらの4つの実装を提供します。

ExponentiallyDecayingReservoir 、http://metrics.dropwizard.io/3.1.0/apidocs/com/codahale/metrics/UniformReservoir.html[ UniformReservoir ]、http://metrics.dropwizard.io/3.1.0/apidocs/com/codahale/metrics/SlidingTimeWindowReservoir.html[ SlidingTimeWindowReservoir ]、 SlidingWindowReservoir .

上記のセクションでは、コンストラクタ __. を使用する以外に MetricRegistry __によってメトリックを作成することもできると述べました。

3.5. タイマー

Timer は、 Context オブジェクトによって表される複数のタイミング期間を追跡するために使用され、それらの統計データも提供します。

Timer timer = new Timer();
Timer.Context context1 = timer.time();
TimeUnit.SECONDS.sleep(5);
long elapsed1 = context1.stop();

assertEquals(5000000000L, elapsed1, 1000000);
assertThat(timer.getCount(), equalTo(1L));
assertEquals(0.2, timer.getMeanRate(), 0.1);

Timer.Context context2 = timer.time();
TimeUnit.SECONDS.sleep(2);
context2.close();

assertThat(timer.getCount(), equalTo(2L));
assertEquals(0.3, timer.getMeanRate(), 0.1);

3.6. レポーター

測定値を出力する必要があるときは、 Reporter を使用できます。これはインターフェースであり、metrics-coreモジュールはhttp://metrics.dropwizard.io/3.1.0/apidocs/com/codahale/metrics/ConsoleReporter.html[ ConsoleReporter ]、httpなどのいくつかの実装を提供します。//metrics.dropwizard.io/3.1.0/apidocs/com/codahale/metrics/CsvReporter.html[ CsvReporter ]、http://metrics.dropwizard.io/3.1.0/apidocs/com/codahale/metrics/Slf4jReporter .html[ Slf4jReporter ]、http://metrics.dropwizard.io/3.1.0/apidocs/com/codahale/metrics/JmxReporter.html[ JmxReporter ]などです。

ここでは例として ConsoleReporter を使用します。

MetricRegistry metricRegistry = new MetricRegistry();

Meter meter = metricRegistry.meter("meter");
meter.mark();
meter.mark(200);
Histogram histogram = metricRegistry.histogram("histogram");
histogram.update(12);
histogram.update(17);
Counter counter = metricRegistry.counter("counter");
counter.inc();
counter.dec();

ConsoleReporter reporter = ConsoleReporter.forRegistry(metricRegistry).build();
reporter.start(5, TimeUnit.MICROSECONDS);
reporter.report();

これは__ConsoleReporterの出力例です。

-- Histograms ------------------------------------------------------------------
histogram
count = 2
min = 12
max = 17
mean = 14.50
stddev = 2.50
median = 17.00
75% <= 17.00
95% <= 17.00
98% <= 17.00
99% <= 17.00
99.9% <= 17.00

-- Meters ----------------------------------------------------------------------
meter
count = 201
mean rate = 1756.87 events/second
1-minute rate = 0.00 events/second
5-minute rate = 0.00 events/second
15-minute rate = 0.00 events/second

4モジュール metrics-healthchecks

Metricsにはヘルスチェックを扱うためのextensions metrics-healthchecksモジュールがあります。

4.1. Mavenの依存関係

metrics-healthchecksモジュールを使用するには、この依存関係を pom.xml ファイルに追加する必要があります。

<dependency>
    <groupId>io.dropwizard.metrics</groupId>
    <artifactId>metrics-healthchecks</artifactId>
    <version>3.1.2</version>
</dependency>

そして、あなたはその最新バージョンを見つけることができますここに]。

4.2. 使用法

まず、特定のヘルスチェック操作を担当するクラスがいくつか必要です。これらのクラスは HealthCheck を実装する必要があります。

たとえば、 DatabaseHealthCheck UserCenterHealthCheck を使用します。

public class DatabaseHealthCheck extends HealthCheck {

    @Override
    protected Result check() throws Exception {
        return Result.healthy();
    }
}
public class UserCenterHealthCheck extends HealthCheck {

    @Override
    protected Result check() throws Exception {
        return Result.healthy();
    }
}

それから、 HealthCheckRegistry (これは MetricRegistry に似ています)を必要とし、それに DatabaseHealthCheck UserCenterHealthCheck を登録します。

HealthCheckRegistry healthCheckRegistry = new HealthCheckRegistry();
healthCheckRegistry.register("db", new DatabaseHealthCheck());
healthCheckRegistry.register("uc", new UserCenterHealthCheck());

assertThat(healthCheckRegistry.getNames().size(), equalTo(2));

HealthCheck の登録を解除することもできます。

healthCheckRegistry.unregister("uc");

assertThat(healthCheckRegistry.getNames().size(), equalTo(1));

すべての HealthCheck インスタンスを実行できます。

Map<String, HealthCheck.Result> results = healthCheckRegistry.runHealthChecks();
for (Map.Entry<String, HealthCheck.Result> entry : results.entrySet()) {
    assertThat(entry.getValue().isHealthy(), equalTo(true));
}

最後に、特定の HealthCheck インスタンスを実行できます。

healthCheckRegistry.runHealthCheck("db");

5モジュール metrics-servlets

メトリックは、HTTPリクエストを通じてメトリック関連データにアクセスできるようにする便利なサーブレットをいくつか提供しています。

5.1. Mavenの依存関係

metrics-servletsモジュールを使用するには、この依存関係を pom.xml ファイルに追加する必要があります。

<dependency>
    <groupId>io.dropwizard.metrics</groupId>
    <artifactId>metrics-servlets</artifactId>
    <version>3.1.2</version>
</dependency>

そして、その最新版はhttps://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22io.dropwizard.metrics%22%20AND%20a%3A%22metrics-servlets%22[ここに]。

5.2. HealthCheckServlet 使用法

HealthCheckServlet はヘルスチェックの結果を提供します。まず、 HealthCheckRegistry を公開する ServletContextListener を作成する必要があります。

public class MyHealthCheckServletContextListener
  extends HealthCheckServlet.ContextListener {

    public static HealthCheckRegistry HEALTH__CHECK__REGISTRY
      = new HealthCheckRegistry();

    static {
        HEALTH__CHECK__REGISTRY.register("db", new DatabaseHealthCheck());
    }

    @Override
    protected HealthCheckRegistry getHealthCheckRegistry() {
        return HEALTH__CHECK__REGISTRY;
    }
}

次に、このリスナーと HealthCheckServlet の両方を web.xml ファイルに追加します。

<listener>
    <listener-class>com.baeldung.metrics.servlets.MyHealthCheckServletContextListener</listener-class>
</listener>
<servlet>
    <servlet-name>healthCheck</servlet-name>
    <servlet-class>com.codahale.metrics.servlets.HealthCheckServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>healthCheck</servlet-name>
    <url-pattern>/healthcheck</url-pattern>
</servlet-mapping>

これでWebアプリケーションを起動し、「http://localhost:8080/healthcheck」にGETリクエストを送信してヘルスチェック結果を取得できます。その応答は次のようになります。

{
  "db": {
    "healthy": true
  }
}

5.3. ThreadDumpServlet 使用法

ThreadDumpServlet は、JVM内のすべてのライブスレッド、それらの状態、それらのスタックトレース、およびそれらが待機している可能性があるロックの状態に関する情報を提供します。使用したい場合は、単に web.xml ファイルにこれらを追加するだけです。

<servlet>
    <servlet-name>threadDump</servlet-name>
    <servlet-class>com.codahale.metrics.servlets.ThreadDumpServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>threadDump</servlet-name>
    <url-pattern>/threaddump</url-pattern>
</servlet-mapping>

スレッドダンプデータは「http://localhost:8080/threaddump」で入手できます。

5.4. PingServlet 使用法

PingServlet は、アプリケーションが実行されているかどうかをテストするために使用できます。これらを web.xml ファイルに追加します。

<servlet>
    <servlet-name>ping</servlet-name>
    <servlet-class>com.codahale.metrics.servlets.PingServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>ping</servlet-name>
    <url-pattern>/ping</url-pattern>
</servlet-mapping>

そして、「http://localhost:8080/ping」にGETリクエストを送信します。応答のステータスコードは200、内容は「pong」です。

5.5. MetricsServlet 使用法

MetricsServlet はメトリックデータを提供します。まず、 MetricRegistry を公開する ServletContextListener を作成する必要があります。

public class MyMetricsServletContextListener
  extends MetricsServlet.ContextListener {
    private static MetricRegistry METRIC__REGISTRY
     = new MetricRegistry();

    static {
        Counter counter = METRIC__REGISTRY.counter("m01-counter");
        counter.inc();

        Histogram histogram = METRIC__REGISTRY.histogram("m02-histogram");
        histogram.update(5);
        histogram.update(20);
        histogram.update(100);
    }

    @Override
    protected MetricRegistry getMetricRegistry() {
        return METRIC__REGISTRY;
    }
}

このリスナーと MetricsServlet の両方を web.xml に追加する必要があります。

<listener>
    <listener-class>com.codahale.metrics.servlets.MyMetricsServletContextListener</listener-class>
</listener>
<servlet>
    <servlet-name>metrics</servlet-name>
    <servlet-class>com.codahale.metrics.servlets.MetricsServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>metrics</servlet-name>
    <url-pattern>/metrics</url-pattern>
</servlet-mapping>

これは、当社のWebアプリケーションの「http://localhost:8080/metrics」で公開されます。その応答にはさまざまなメトリクスデータが含まれているはずです。

{
  "version": "3.0.0",
  "gauges": {},
  "counters": {
    "m01-counter": {
      "count": 1
    }
  },
  "histograms": {
    "m02-histogram": {
      "count": 3,
      "max": 100,
      "mean": 41.66666666666666,
      "min": 5,
      "p50": 20,
      "p75": 100,
      "p95": 100,
      "p98": 100,
      "p99": 100,
      "p999": 100,
      "stddev": 41.69998667732268
    }
  },
  "meters": {},
  "timers": {}
}

5.6. AdminServlet 使用法

AdminServlet は、 HealthCheckServlet ThreadDumpServlet MetricsServlet 、および PingServlet を集約します。

これらを web.xml に追加しましょう。

<servlet>
    <servlet-name>admin</servlet-name>
    <servlet-class>com.codahale.metrics.servlets.AdminServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>admin</servlet-name>
    <url-pattern>/admin/** </url-pattern>
</servlet-mapping>

それは今「http://localhost:8080/admin」でアクセスすることができます。 4つのサーブレットそれぞれに1つずつ、合計4つのリンクを含むページが表示されます。

ヘルスチェックを実行してメトリクスデータにアクセスする場合は、これら2つのリスナーがまだ必要です。

6. モジュール metrics-servlet

metrics-servlet モジュールは Filter を提供します。これはいくつかの測定基準を持っています:ステータスコードのメーター、アクティブなリクエストの数のカウンター、そしてリクエスト期間のタイマー。

6.1. Mavenの依存関係

このモジュールを使用するには、まず pom.xml に依存関係を追加しましょう。

<dependency>
    <groupId>io.dropwizard.metrics</groupId>
    <artifactId>metrics-servlet</artifactId>
    <version>3.1.2</version>
</dependency>

そして、あなたはその最新版を見つけることができますhttps://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22io.dropwizard.metrics%22%20AND%20a%3A%22metrics-servlet%22[ここに]。

6.2. 使用法

それを使うには、 MetricRegistry InstrumentedFilter に公開する ServletContextListener を作成する必要があります。

public class MyInstrumentedFilterContextListener
  extends InstrumentedFilterContextListener {

    public static MetricRegistry REGISTRY = new MetricRegistry();

    @Override
    protected MetricRegistry getMetricRegistry() {
        return REGISTRY;
    }
}

次に、これらを web.xml に追加します。

<listener>
     <listener-class>
         com.baeldung.metrics.servlet.MyInstrumentedFilterContextListener
     </listener-class>
</listener>

<filter>
    <filter-name>instrumentFilter</filter-name>
    <filter-class>
        com.codahale.metrics.servlet.InstrumentedFilter
    </filter-class>
</filter>
<filter-mapping>
    <filter-name>instrumentFilter</filter-name>
    <url-pattern>/** </url-pattern>
</filter-mapping>

これで InstrumentedFilter が機能します。そのメトリックデータにアクセスしたい場合は、その MetricRegistry REGISTRY を介してアクセスできます。

7. その他のモジュール

上記で紹介したモジュールを除いて、Metricsにはさまざまな目的のためのモジュールがいくつかあります。

  • metrics-jvm :JVMをインスツルメントするための便利なメトリックをいくつか提供します。

内部 ** metrics-ehcache : InstrumentedEhcache を提供します。

Ehcacheキャッシュ ** metrics-httpclient :Apacheをインスツルメントするためのクラスを提供します

HttpClient(4.xバージョン) ** metrics-log4j :Log4j Appender として InstrumentedAppender を提供

によって記録されたイベントの割合を記録するlog4j 1.xの実装 ロギングレベル ** metrics-log4j2 :log4j 2.xを除いて、metrics-log4jに似ています

  • metrics-logback :Logbackである InstrumentedAppender を提供します

記録されたイベントの割合を記録する Appender 実装 ロギングレベル ** metrics-json : HealthCheckModule MetricsModule を提供します。

ジャクソン

さらに、これらの主要なプロジェクトモジュール以外に、他のライブラリやフレームワークとの統合を提供するhttp://metrics.dropwizard.io/3.1.0/manual/third-party/[サードパーティライブラリ]があります。

8結論

アプリケーションのインスツルメンテーションは一般的な要件であるため、この記事では、問題の解決に役立つことを期待してMetricsを紹介しました。

いつものように、この例の完全なソースコードはhttps://github.com/eugenp/tutorials/tree/master/metrics[GitHubで利用可能]です。