マイクロメータクイックガイド

[[1-introduction]]

1前書き

Micrometer ** いくつかの一般的な監視システムについて、インストルメンテーションクライアントの上にシンプルな外観を提供します。 、グラファイト、ガングリア、インフラックス、JMXおよびプロメテウス。

この記事では、Micrometerの基本的な使い方とSpringとの統合について紹介します。

わかりやすくするために、Micrometer Atlasを例として使用して、ほとんどのユースケースを説明します。

[[2-maven-dependency]]

2 Mavenの依存関係

まず、 pom.xml に次の依存関係を追加しましょう。

<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-registry-atlas</artifactId>
    <version>0.12.0.RELEASE</version>
</dependency>

最新版はhttps://search.maven.org/classic/#search%7Cga%7C1%7Ca%3A%22micrometer-registry-atlas%22%20AND%20g%3A%20%22io.micrometer%22にあります。[ここに]。

[[3-registry]]

3 MeterRegistry

マイクロメータでは、https://github.com/micrometer-metrics/micrometer/blob/master/micrometer-core/src/main/java/io/micrometer/core/instrument/MeterRegistry.java#L41[ MeterRegistry ]がメーターの登録に使用されるコアコンポーネント。レジストリと各メーターの測定基準を繰り返し処理して、測定基準とそのディメンション値を組み合わせたバックエンドの時系列を生成できます。

レジストリの最も簡単な形式はhttps://github.com/micrometer-metrics/micrometer/blob/master/micrometer-core/src/main/java/io/micrometer/core/instrument/simple/SimpleMeterRegistry.java#L31です。[ SimpleMeterRegistry ]。

しかし、ほとんどの場合、https://github.com/micrometer-metrics/micrometer/blob/master/micrometer-core/src/main/java/io/micrometer/core/instrument/MeterRegistry.java#L41を使用する必要があります。[ MeterRegistry ]は、私たちの監視システム用に明示的に設計されています。 Atlasの場合はhttps://github.com/micrometer-metrics/micrometer/blob/master/implementations/micrometer-registry-atlas/src/main/java/io/micrometer/atlas/AtlasMeterRegistry.java#L36[ AtlasMeterRegistry ]。

CompositeMeterRegistry により、複数のレジストリが追加されます。サポートされているさまざまな監視システムに同時にアプリケーションメトリックを公開するためのソリューションを提供します。

データを複数のプラットフォームにアップロードするのに必要な MeterRegistry を追加できます。

CompositeMeterRegistry compositeRegistry = new CompositeMeterRegistry();
SimpleMeterRegistry oneSimpleMeter = new SimpleMeterRegistry();
AtlasMeterRegistry atlasMeterRegistry
  = new AtlasMeterRegistry(atlasConfig, Clock.SYSTEM);

compositeRegistry.add(oneSimpleMeter);
compositeRegistry.add(atlasMeterRegistry);

Micrometerには静的なグローバルレジストリサポートがあります。

また、https://github.com/micrometer-metrics/micrometer/blob/master/micrometer-core/src/main/java/io/micrometer/にメーターを生成するための、このグローバルレジストリに基づく一連の静的ビルダーが提供されています。 core/instrument/Metrics.java#L30[ Metrics ]:

@Test
public void givenGlobalRegistry__whenIncrementAnywhere__thenCounted() {
    class CountedObject {
        private CountedObject() {
            Metrics.counter("objects.instance").increment(1.0);
        }
    }
    Metrics.addRegistry(new SimpleMeterRegistry());

    Metrics.counter("objects.instance").increment();
    new CountedObject();

    Optional<Counter> counterOptional = Metrics.globalRegistry
      .find("objects.instance").counter();
    assertTrue(counterOptional.isPresent());
    assertTrue(counterOptional.get().count() == 2.0);
}

[[4-meters]]

4 タグ メーター

4.1. タグ

Meter の識別子は、名前とタグ複数のモニタリングシステム間でメトリック名の移植性を保証するために、単語をドットで区切る命名規則に従う必要があります。

Counter counter = registry.counter("page.visitors", "age", "20s");

スライスにはhttps://github.com/micrometer-metrics/micrometer/blob/master/micrometer-core/src/main/java/io/micrometer/core/instrument/Tag.java#L23[ Tags ]を使用できます。値を推論するためのメトリック。上記のコードでは、 page.visitors がメーターの名前で、 age = 20s がタグとして含まれています。この場合、カウンタは、ページへの訪問者を20歳から30歳までの年齢で数えるためのものです。

大規模システムでは、メトリックが特定の地域からのものであると言って、共通のタグをレジストリに追加できます。

registry.config().commonTags("region", "ua-east");

4.2. カウンタ

Counter は、単なるカウントオーバーを報告します。アプリケーションの指定されたプロパティ流れるようなビルダーまたは任意の MetricRegistry のヘルパーメソッドを使用してカスタムカウンターを構築できます。

Counter counter = Counter
  .builder("instance")
  .description("indicates instance count of the object")
  .tags("dev", "performance")
  .register(registry);

counter.increment(2.0);

assertTrue(counter.count() == 2);

counter.increment(-1);

assertTrue(counter.count() == 2);

上のスニペットからわかるように、カウンタを1つ減らすことを試みましたが、カウンタを単調に固定の正の量だけ増やすことができます。

4.3. タイマー

システムの待ち時間やイベントの頻度を測定するには、 https://github.com/micrometer-metrics/micrometer/blob/master/micrometer-core/src/main/java/io/micrometer/core/instrument/を使用できます。 Timer.java#L34[タイマー]

Timer は、少なくとも特定の時系列の合計時間とイベント数を報告します。

たとえば、数秒間続くアプリケーションイベントを記録できます。

SimpleMeterRegistry registry = new SimpleMeterRegistry();
Timer timer = registry.timer("app.event");
timer.record(() -> {
    try {
        TimeUnit.MILLISECONDS.sleep(1500);
    } catch (InterruptedException ignored) { }
});

timer.record(3000, MILLISECONDS);

assertTrue(2 == timer.count());
assertTrue(4510 > timer.totalTime(MILLISECONDS)
  && 4500 <= timer.totalTime(MILLISECONDS));

長時間のイベントを記録するには、https://github.com/micrometer-metrics/micrometer/blob/master/micrometer-core/src/main/java/io/micrometer/core/instrument/LongTaskTimer.java#を使用しますL26[ ロングタスクタイマー ]:

SimpleMeterRegistry registry = new SimpleMeterRegistry();
LongTaskTimer longTaskTimer = LongTaskTimer
  .builder("3rdPartyService")
  .register(registry);

long currentTaskId = longTaskTimer.start();
try {
    TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException ignored) { }
long timeElapsed = longTaskTimer.stop(currentTaskId);

assertTrue(timeElapsed/(int) 1e9 == 2);

4.4. ゲージ

ゲージはメーターの現在の値を示します。

他のメーターとは異なり、https://github.com/micrometer-metrics/micrometer/blob/master/micrometer-core/src/main/java/io/micrometer/core/instrument/Gauge.java#L23[ Gauges ]観察時にのみデータを報告します。 Gauges はキャッシュやコレクションなどの統計を監視するときに便利です。

SimpleMeterRegistry registry = new SimpleMeterRegistry();
List<String> list = new ArrayList<>(4);

Gauge gauge = Gauge
  .builder("cache.size", list, List::size)
  .register(registry);

assertTrue(gauge.value() == 0.0);

list.add("1");

assertTrue(gauge.value() == 1.0);

4.5. 分配合計

イベントの分布と簡単な要約はhttps://github.com/micrometer-metrics/micrometer/blob/master/micrometer-core/src/main/java/io/micrometer/core/instrument/DistributionSummary.java#によって提供されます。 L29[ 分配合計 ]:

SimpleMeterRegistry registry = new SimpleMeterRegistry();
DistributionSummary distributionSummary = DistributionSummary
  .builder("request.size")
  .baseUnit("bytes")
  .register(registry);

distributionSummary.record(3);
distributionSummary.record(4);
distributionSummary.record(5);

assertTrue(3 == distributionSummary.count());
assertTrue(12 == distributionSummary.totalAmount());

さらに、 DistributionSummary Timers は分位数で強化できます。

SimpleMeterRegistry registry = new SimpleMeterRegistry();
Timer timer = Timer.builder("test.timer")
  .quantiles(WindowSketchQuantiles
    .quantiles(0.3, 0.5, 0.95)
    .create())
  .register(registry);

上記のスニペットでは、 quantile = 0.3 quantile = 0.5 、および quantile = 0.95 のタグを持つ3つのゲージがレジストリで使用可能になり、それぞれ95%、50%、および30%の観測値を下回る値を示します。

これらの分位点の動作を確認するには、次のレコードを追加しましょう。

timer.record(2, TimeUnit.SECONDS);
timer.record(2, TimeUnit.SECONDS);
timer.record(3, TimeUnit.SECONDS);
timer.record(4, TimeUnit.SECONDS);
timer.record(8, TimeUnit.SECONDS);
timer.record(13, TimeUnit.SECONDS);

それから、これら3つの分位数 Gauges の値を抽出することで検証できます。

List<Gauge> quantileGauges = registry.getMeters().stream()
  .filter(m -> m.getType().name().equals("Gauge"))
  .map(meter -> (Gauge) meter)
  .collect(Collectors.toList());

assertTrue(3 == quantileGauges.size());

Map<String, Integer> quantileMap = extractTagValueMap(registry, Type.Gauge, 1e9);
assertThat(quantileMap, allOf(
  hasEntry("quantile=0.3",2),
  hasEntry("quantile=0.5", 3),
  hasEntry("quantile=0.95", 8)));

その上、Micrometerはヒストグラムもサポートしています。

DistributionSummary hist = DistributionSummary
  .builder("summary")
  .histogram(Histogram.linear(0, 10, 5))
  .register(registry);

変位値と同様に、複数のレコードを追加した後、ヒストグラムが計算をうまく処理していることがわかります。

Map<String, Integer> histograms = extractTagValueMap(registry, Type.Counter, 1.0);
assertThat(histograms, allOf(
  hasEntry("bucket=0.0", 0),
  hasEntry("bucket=10.0", 2),
  hasEntry("bucket=20.0", 2),
  hasEntry("bucket=30.0", 1),
  hasEntry("bucket=40.0", 1),
  hasEntry("bucket=Infinity", 0)));

一般に、ヒストグラムは別々のバケットで直接比較するのに役立ちます。ヒストグラムは時間スケールすることもできます。これはバックエンドサービスの応答時間を分析するのに非常に役立ちます。

SimpleMeterRegistry registry = new SimpleMeterRegistry();
Timer timer = Timer
  .builder("timer")
  .histogram(Histogram.linearTime(TimeUnit.MILLISECONDS, 0, 200, 3))
  .register(registry);
//...
assertThat(histograms, allOf(
  hasEntry("bucket=0.0", 0),
  hasEntry("bucket=2.0E8", 1),
  hasEntry("bucket=4.0E8", 1),
  hasEntry("bucket=Infinity", 3)));

[[5-binders]]

5バインダー

Micrometerには、JVM、キャッシュ、 ExecutorService 、ロギングサービスを監視するための複数の組み込みバインダーがあります。

JVMとシステムの監視に関しては、クラスローダーメトリックスを監視できます(https://github.com/micrometer-metrics/micrometer/blob/master/micrometer-core/src/main/java/io/micrometer/core/instrument/バインダー/jvm/ClassLoaderMetrics.java#L27[ ClassLoaderMetrics ])、JVMメモリプール(https://github.com/micrometer-metrics/micrometer/blob/master/micrometer-core/src/main/java/io/)マイクロメーター/コア/機器/バインダー/jvm/JvmMemoryMetrics.java#L38[ JvmMemoryMetrics ])およびGCメトリックス(https://github.com/micrometer-metrics/micrometer/blob/master/micrometer-core/src/main/java)/io/micrometer/core/instrument/binder/jvm/JvmGcMetrics.java#L45[ JvmGcMetrics ])、スレッドとCPUの使用率(https://github.com/micrometer-metrics/micrometer/blob/master/micrometer-core/) src/main/java/io/マイクロメートル/コア/楽器/バインダー/jvm/JvmThreadMetrics.java#L27[ JvmThreadMetrics ]、https://github.com/micrometer-metrics/micrometer/blob/master/micrometer-core/src/main/java/io/マイクロメータ/コア/計測器/バインダ/システム/プロセッサMetrics.java#L30[ ProcessorMetrics ])。

キャッシュ監視(現在、Guava、EhCache、Hazelcast、およびCaffeineのみがサポートされています)は、https://github.com/micrometer-metrics/micrometer/blob/master/micrometer-core/src/main/java/で計測することでサポートされていますio/マイクロメーター/コア/楽器/バインダー/キャッシュ/GuavaCacheMetrics.java#L31[ GuavaCacheMetrics ]、https://github.com/micrometer-metrics/micrometer/blob/master/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/cache/EhCache2Metrics.java#L28[ EhCache2Metrics ]、https://github.com/micrometer-metrics/micrometer/blob/master/micrometer-core/src/main/java/io/マイクロメーター/コア/機器/バインダー/キャッシュ/HazelcastCacheMetrics.java#L27[ HazelcastCacheMetrics ]、およびhttps://github.com/micrometer-metrics/micrometer/blob/master/micrometer-core/src/main/java/io/マイクロメーター/コア/機器/バインダー/キャッシュ/CaffeineCacheMetrics.java#L42[ CaffeineCacheMetrics ]。

そして、ログバックサービスを監視するために、https://github.com/micrometer-metrics/micrometer/blob/master/micrometer-core/src/main/java/io/micrometer/core/instrument/binder/logging/をバインドすることができます。有効なレジストリにLogbackMetrics.java#L36[ LogbackMetrics ]を追加します。

new LogbackMetrics().bind(registry);

上記のバインダーの使い方は LogbackMetrics と非常によく似ていて、どちらもかなり単純なので、ここではこれ以上詳しく説明しません。

[[6-spring-integration]]

6. 春の統合

  • Spring Boot Actuatorは、Micrometerの依存関係管理と自動設定を提供します** Spring Boot 2.0/1.xとSpring Framework 5.0/4.xでサポートされるようになりました。

次の依存関係が必要になります(最新バージョンはhttps://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22io.micrometer%22%20AND%20a%3A%22micrometerにあります-spring-legacy%22[ここ]):

<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-spring-legacy</artifactId>
    <version>0.12.0.RELEASE</version>
</dependency>

既存のコードをこれ以上変更することなく、MicrometerでSpringのサポートを有効にしました。 SpringアプリケーションのJVMメモリメトリックは自動的にグローバルレジストリに登録され、デフォルトのアトラスエンドポイントに公開されます。

spring.metrics.atlas。** から始まる、メトリックのエクスポート動作を制御するための設定可能なプロパティがいくつかあります。アトラスパブリッシングの設定プロパティの完全なリストを見るためにhttp://netflix.github.io/spectator/en/latest/javadoc/spectator-reg-atlas/com/netflix/spectator/atlas/AtlasConfig.html[ AtlasConfig ]をチェックする。

さらにメトリックをバインドする必要がある場合は、それらを @ Bean としてアプリケーションコンテキストに追加するだけです。

JvmThreadMetrics が必要だとします。

@Bean
JvmThreadMetrics threadMetrics(){
    return new JvmThreadMetrics();
}

ウェブモニタリングに関しては、それは我々のアプリケーションのすべてのエンドポイントに対して自動設定されていますが、設定プロパティを通して管理可能です:

spring.metrics.web.autoTimeServerRequests

  • デフォルトの実装はエンドポイントのための4つのディメンションのメトリックを提供します:HTTPリクエストメソッド、HTTPレスポンスコード、エンドポイントURI、そして例外情報

要求に応答すると、要求方法に関するメトリック( GET POST など)がAtlasに公開されます。

Atlas Graph API を使用すると、さまざまなメソッドの応答時間を比較するためのグラフを生成できます。

リンク:/uploads/methods-768x466.png%20768w[]

デフォルトでは、応答コード 20x 30x 40x 50x も報告されます。

リンク:/uploads/status-768x576.png%20768w[]

異なるURIを比較することもできます。

リンク:/uploads/uri-768x521.png%20768w[]

または例外メトリクスを確認します。

リンク:/uploads/exception-768x466.png%20768w[]

@RestController
@Timed("people")
public class PeopleController {

    @GetMapping("/people")
    @Timed(value = "people.all", longTask = true)
    public List<String> listPeople() {
       //...
    }

}

上記のコードに基づいて、Atlasエンドポイント http://localhost:7101/api/v1/tags/name を確認すると、次のタグがわかります。

----["people", "people.all", "jvmBufferCount", ...]----

Micrometerは、Spring Boot 2.0で導入された機能Webフレームワークでも機能します。メトリックは、 RouterFunction をフィルタリングすることによって有効にすることができます。

RouterFunctionMetrics metrics = new RouterFunctionMetrics(registry);
RouterFunctions.route(...)
  .filter(metrics.timer("server.requests"));

データソースとスケジュールされたタスクからのメトリックも収集できます。

詳しくはhttp://micrometer.io/docs/atlas#__scheduling[official documentation]をご覧ください。

[[7-summary]]

7. 結論

この記事では、Micrometerのメトリックファサードを紹介しました。共通のセマンティクスの下で複数の監視システムを抽象化してサポートすることで、このツールは異なる監視プラットフォーム間の切り替えを非常に簡単にします。

いつものように、この記事の完全な実装コードはhttps://github.com/eugenp/tutorials/tree/master/metrics[over on Github]にあります。