😎

Micrometerを用いたCloudWatchMetricsでの独自メトリクス管理

2024/03/05に公開

はじめに

JavaおよびSpringBootを用いたアプリケーションで、Micrometerを用いて
CloudWatchMetricsへ独自メトリクスとしてエクスポートするための方法をメモとして残します。
(その他、学習したネタも多少含みます。)

メトリクスを得る意味

システムにおいてメトリクスを得ることは、そのシステムのパフォーマンス、健全性、および全体的な運用効率を理解し、改善するために不可欠です。

クラウドサービスから提供されているメトリクス

サーバーのCPU使用率やメモリ使用率、Queueの滞留などはクラウドサービス側で公開されているメトリクスであることが多いです。
それらは主に非機能要件の確認などのために用いられます。

パフォーマンスの監視

メトリクスを通じて、システムがどの程度効率的に機能しているかを評価できます。これには応答時間、処理速度、リソース使用率などが含まれます。

問題の特定と診断

異常やパフォーマンスの低下を示すメトリクスを監視することで、問題が発生する前にそれを特定し、迅速に対処することができます。これは、システムダウンタイムを最小限に抑え、利用者の満足度を維持するのに役立ちます。

キャパシティプランニング

メトリクスを分析することで、将来の成長や需要の増加に備えて、システムリソースの適切な拡張を計画することができます。これにより、過負荷やパフォーマンスのボトルネックを避けることができます。

品質保証と改善

メトリクスは、システムの品質を継続的に監視し、問題を特定して解決するためのフィードバックループを提供します。これにより、システムの安定性、信頼性、およびユーザーエクスペリエンスを向上させることができます。

クラウドサービスから提供されていない独自のメトリクス

一方で、クラウドサービス側で公開することのできない業務的な意味を持つメトリクスなどは自分自身でモニタリングツールやプラットフォームへエクスポートする必要があります。それらは主に目標管理や業務分析および改善に用いられます。

意思決定のサポート

適切なメトリクスは、リソース割り当て、技術的な選択、そして戦略的方向性を決定する際の重要な情報を提供します。データ駆動型の意思決定は、より効果的で効率的な結果をもたらすことができます。

コンプライアンスと監査

特定の業界や用途では、規制要件や基準に準拠していることを証明するためにメトリクスが必要になる場合があります。
これはメトリクスだけでは必要な情報が揃わない場合もありますが、監査やレビューのプロセスをサポートしコンプライアンスを確保するのに役立つこともあります。

透明性とコミュニケーション

メトリクスは、チームメンバーやステークホルダー間での透明性とコミュニケーションを促進します。共有されたデータと洞察は、協力とアライメントを促進し、より一貫した目標達成に貢献します。

システムのメトリクスを取得することは、単に数字を追跡すること以上の意味を持ちます。
それは、システムの健全性を維持し、最適化するための基盤を形成し、持続可能な成長と改善を可能にします。

Micrometerとは

JavaのMicrometerは、Javaアプリケーションでメトリクスを収集し、モニタリングするためのライブラリです。Micrometerは、アプリケーションの性能や動作を追跡するための統一されたAPIを提供し、さまざまなメトリクスを収集するための柔軟な方法を提供します。

Micrometerを使用すると、以下のようなメトリクスを収集できます。

  • Counter(カウンター): アプリケーション内で特定のイベントが発生した回数をカウントします。
  • Gauge(ゲージ): 特定の値やサイズを追跡します。例えば、メモリ使用量やキャッシュのサイズなど。
  • Timer(タイマー): 特定の処理やメソッドの実行時間を計測します。
  • その他:TimerやDistributionSummaryを利用したデータの分布を表したヒストグラム

Micrometerは、Prometheus、Datadog、Graphite、NewRelicなどのさまざまなモニタリングツールやプラットフォームにメトリクスをエクスポートする機能も提供しています。これにより、アプリケーションのパフォーマンスをリアルタイムで監視したり、過去のデータを分析したりすることができます。
今回は、AWSのCloudWatchMetricsへのエクスポートを対象にしたいと思います。

前提

この記事は、以下のソフトウェアスタックを利用している前提となります。

  • Java17
  • Spring Boot 3.1.X
    • starter-web などを利用した常駐アプリ
  • Spring Cloud
  • Spring Cloud AWS

依存関係の追加

前提となるソフトウェアスタックを利用している場合は、
以下の依存関係を追加するのみでOKです。

Mavenの場合

<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-registry-cloudwatch2</artifactId>
    <version>最新のバージョン</version>
</dependency>

Gradleの場合

implementation 'io.micrometer:micrometer-registry-cloudwatch2:最新のバージョン'

MeterRegistryの定義

application.properties または application.yml に定義する場合と、JavaConfigを書く場合があります。

application.propertiesの例

management.metrics.export.cloudwatch.namespace=メトリクスの名前空間
management.metrics.export.cloudwatch.step=1m # <1>

<1> : メトリクスの収集感覚です。Suffixを「s」にすると秒、「m」にすると分です。

JavaConfigの例


@Bean
public CloudWatchAsyncClient cloudWatchAsyncClient() {
  return CloudWatchAsyncClient.builder().region(Region.AP_NORTHEAST_1).build();
}

@Bean
public CloudWatchConfig cloudWatchConfig() {
    return new CloudWatchConfig() {
        private Map<String, String> configuration = 
          Map.of(
            "cloudwatch.namespace", "メトリクスの名前空間",
            "cloudwatch.step", "1"
          );
        @Override
        public String get(String key) {
            return configuration.get(key);
        }
    }
}

@Bean("myCustomMetricsRegistry")
public MeterRegistry myCustomMetricsRegistry(
  CloudWatchConfig cloudWatchConfig, 
  CloudWatchAsyncClient cloudWatchAsyncClient) {
  return new CloudWatchMeterRegistry(
    cloudWatchConfig, 
    Clock.SYSTEM, 
    cloudWatchAsyncClient);
}

メトリクス値の登録

何かの処理に合わせて値のExportを行うなど、任意のタイミングでのメトリクス値の登録を行えます。


@Component
@AllArgsConstructor
public class SomeBusinessLogic {

  final MeterRegistry myCustomMetricsRegistry;

  // omitted...

  public void process() {
  
    // omitted...

    myCustomMetricsRegistry.gauge("example.metrics.name", 1);

    // omitted...

  }

}


まとめ

Micrometerを用いて、簡単に独自メトリクスを得ることができますが、大事なことはこのメトリクスを定期的に確認することだと思います。
こういったメトリクスはダッシュボードで管理して人が見やすい形に整理することがおおいですので、今後はそれらをネタにしてメモをできればと思います。

記載内容について誤りやご意見がありましたら、コメントいただけると幸いです。
誤りがある場合は、間違った情報を拡散しないように修正いたします。

Discussion