Dropwizardメトリックスの紹介
1. 前書き
Metricsは、Javaアプリケーション用の測定器を提供するJavaライブラリです。
いくつかのモジュールがありますが、この記事では、metrics-coreモジュール、metrics-healthchecksモジュール、metrics-servletsモジュール、metrics-servletモジュールについて詳しく説明し、残りを参照用にスケッチします。
2. モジュールmetrics-core
2.1. Mavenの依存関係
metrics-coreモジュールを使用するには、pom.xmlファイルに追加する必要がある依存関係が1つだけあります。
io.dropwizard.metrics
metrics-core
3.1.2
そして、あなたはその最新バージョンhereを見つけることができます。
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つの基本的な方法があります。自分でインスタンスを作成するか、メトリックレジストリから取得する方法です。 ご覧のとおり、上記の例では両方を使用し、Meterオブジェクト「meter1」をインスタンス化し、metricRegistryによって作成された別のMeterオブジェクト「meter2」を取得しています。 )s。
上記のメトリック名として「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. メトリックの概念
メトリックコアモジュールは、いくつかの一般的に使用されるメトリックタイプを提供します:Meter、Gauge、Counter、HistogramとTimer、およびReporterを出力しますメトリックの値.
3.1. Meter
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オブジェクトは、Meterの存続期間全体、最近1分間、最近5分間、および最近四半期の平均レートをそれぞれ表す4つのレートを提供します。
3.2. Gauge
Gaugeは、特定の値を返すために使用されるインターフェイスです。 メトリックコアモジュールは、RatioGauge、CachedGauge、DerivativeGauge、および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は、値をキャッシュできる別の抽象クラスであるため、値の計算にコストがかかる場合に非常に役立ちます。 これを使用するには、クラスActiveUsersGaugeを実装する必要があります。
public class ActiveUsersGauge extends CachedGauge> {
@Override
protected List loadValue() {
return getActiveUserCount();
}
private List getActiveUserCount() {
List result = new ArrayList();
result.add(12L);
return result;
}
// standard constructors
}
次に、期待どおりに機能するかどうかをテストします。
Gauge> activeUsersGauge = new ActiveUsersGauge(15, TimeUnit.MINUTES);
List expected = new ArrayList<>();
expected.add(12L);
assertThat(activeUsersGauge.getValue(), equalTo(expected));
ActiveUsersGaugeをインスタンス化するときに、キャッシュの有効期限を15分に設定します。
DerivativeGaugeも抽象クラスであり、他のGaugeから値をその値として導出できます。
例を見てみましょう:
public class ActiveUserCountGauge extends DerivativeGauge, Integer> {
@Override
protected Integer transform(List value) {
return value.size();
}
// standard constructors
}
このGaugeは、その値をActiveUsersGaugeから導出するため、基本リストのサイズからの値であると予想されます。
Gauge> activeUsersGauge = new ActiveUsersGauge(15, TimeUnit.MINUTES);
Gauge activeUserCountGauge = new ActiveUserCountGauge(activeUsersGauge);
assertThat(activeUserCountGauge.getValue(), equalTo(1));
JmxAttributeGaugeは、JMXを介して公開されている他のライブラリのメトリックにアクセスする必要がある場合に使用されます。
3.3. Counter
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
Histogramは、Long値のストリームを追跡するために使用され、max, min, mean, median, standard deviation, 75th percentileなどの統計的特性を分析します。
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));
Histogramは、リザーバーサンプリングを使用してデータをサンプリングします。Histogramオブジェクトをインスタンス化するときは、そのリザーバーを明示的に設定する必要があります。
Reservoirはインターフェースであり、metrics-coreはそれらの4つの実装を提供します:ExponentiallyDecayingReservoir、UniformReservoir、SlidingTimeWindowReservoir、SlidingWindowReservoir.
上記のセクションでは、コンストラクター.を使用する以外に、MetricRegistry,によってメトリックを作成することもできると述べました。metricRegistry.histogram()を使用すると、HistogramインスタンスがExponentiallyDecayingReservoirの実装。
3.5. Timer
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
測定値を出力する必要がある場合は、Reporterを使用できます。 これはインターフェースであり、metrics-coreモジュールは、ConsoleReporter、CsvReporter、Slf4jReporter、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
メトリックスには、ヘルスチェックを処理するための拡張メトリックス-ヘルスチェックモジュールがあります。
4.1. Mavenの依存関係
metrics-healthchecksモジュールを使用するには、この依存関係をpom.xmlファイルに追加する必要があります。
io.dropwizard.metrics
metrics-healthchecks
3.1.2
そして、あなたはその最新バージョンhereを見つけることができます。
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 results = healthCheckRegistry.runHealthChecks();
for (Map.Entry entry : results.entrySet()) {
assertThat(entry.getValue().isHealthy(), equalTo(true));
}
最後に、特定のHealthCheckインスタンスを実行できます。
healthCheckRegistry.runHealthCheck("db");
5. モジュールmetrics-servlets
メトリックは、HTTPリクエストを介してメトリック関連のデータにアクセスできる便利なサーブレットをいくつか提供します。
5.1. Mavenの依存関係
メトリックサーボモジュールを使用するには、この依存関係をpom.xmlファイルに追加する必要があります。
io.dropwizard.metrics
metrics-servlets
3.1.2
そして、あなたはその最新バージョンhereを見つけることができます。
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ファイルに追加します。
com.example.metrics.servlets.MyHealthCheckServletContextListener
healthCheck
com.codahale.metrics.servlets.HealthCheckServlet
healthCheck
/healthcheck
これで、Webアプリケーションを起動し、「http:// localhost:8080 / healthcheck」にGETリクエストを送信して、ヘルスチェック結果を取得できます。 その応答は次のようになります。
{
"db": {
"healthy": true
}
}
5.3. ThreadDumpServlet使用法
ThreadDumpServletは、JVM内のすべてのライブスレッド、それらの状態、それらのスタックトレース、およびそれらが待機している可能性のあるロックの状態に関する情報を提供します。 これを使用する場合は、これらをweb.xmlファイルに追加するだけです。
threadDump
com.codahale.metrics.servlets.ThreadDumpServlet
threadDump
/threaddump
スレッドダンプデータは、「http:// localhost:8080 / threaddump」で入手できます。
5.4. PingServlet使用法
PingServletを使用して、アプリケーションが実行されているかどうかをテストできます。 これらをweb.xmlファイルに追加します。
ping
com.codahale.metrics.servlets.PingServlet
ping
/ping
次に、GET要求を「http:// localhost:8080 / ping」に送信します。 応答のステータスコードは200で、その内容は「ポン」です。
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に追加する必要があります。
com.codahale.metrics.servlets.MyMetricsServletContextListener
metrics
com.codahale.metrics.servlets.MetricsServlet
metrics
/metrics
これは、「http:// localhost:8080 / metrics」のWebアプリケーションで公開されます。 その応答には、さまざまなメトリックデータが含まれている必要があります。
{
"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に追加しましょう:
admin
com.codahale.metrics.servlets.AdminServlet
admin
/admin/*
これで、「http:// localhost:8080 / admin」でアクセスできます。 これらの4つのサーブレットのそれぞれに1つずつ、4つのリンクを含むページを取得します。
ヘルスチェックを行い、メトリックデータにアクセスする場合、これらの2つのリスナーが引き続き必要であることに注意してください。
6. モジュールmetrics-servlet
metrics-servletモジュールは、いくつかのメトリックを持つFilterを提供します。ステータスコードのメーター、アクティブな要求の数のカウンター、および要求期間のタイマーです。
6.1. Mavenの依存関係
このモジュールを使用するには、最初に依存関係をpom.xmlに追加しましょう。
io.dropwizard.metrics
metrics-servlet
3.1.2
そして、あなたはその最新バージョンhereを見つけることができます。
6.2. 使用法
これを使用するには、MetricRegistryをInstrumentedFilterに公開するServletContextListenerを作成する必要があります。
public class MyInstrumentedFilterContextListener
extends InstrumentedFilterContextListener {
public static MetricRegistry REGISTRY = new MetricRegistry();
@Override
protected MetricRegistry getMetricRegistry() {
return REGISTRY;
}
}
次に、これらをweb.xmlに追加します。
com.example.metrics.servlet.MyInstrumentedFilterContextListener
instrumentFilter
com.codahale.metrics.servlet.InstrumentedFilter
instrumentFilter
/*
これで、InstrumentedFilterが機能します。 メトリックデータにアクセスする場合は、MetricRegistryREGISTRYを介してアクセスできます。
7. その他のモジュール
上記で紹介したモジュールを除き、Metricsにはさまざまな目的のための他のモジュールがいくつかあります。
-
metrics-jvm:JVM内部をインストルメント化するためのいくつかの有用なメトリックを提供します
-
metrics-ehcache:EhcacheキャッシュのデコレータであるInstrumentedEhcacheを提供します
-
metrics-httpclient:Apache HttpClient(4.xバージョン)をインストルメント化するためのクラスを提供します
-
metrics-log4j:ログレベルごとにログイベントの割合を記録するlog4j 1.xのLog4jAppender実装であるInstrumentedAppenderを提供します
-
metrics-log4j2:log4j 2.xの場合のみ、metric-log4jに似ています
-
metrics-logback:ログレベルごとにログイベントの割合を記録するログバックAppender実装であるInstrumentedAppenderを提供します
-
metrics-json:ジャクソンにHealthCheckModuleとMetricsModuleを提供します
さらに、これらのメインプロジェクトモジュール以外に、他のいくつかのthird party librariesが他のライブラリやフレームワークとの統合を提供します。
8. 結論
アプリケーションのインスツルメンテーションは一般的な要件であるため、この記事では、問題の解決に役立つことを期待して、メトリックを紹介しました。
いつものように、この例の完全なソースコードはover on GitHubで入手できます。