App Runner上でのメトリックス監視のためのSpring BootとCloudWatchの設定

はじめに

先日、AWS App Runner上で動くコンテナ化したSpring Bootアプリケーションの可観測性に関する実装の一環でトレースをX-Rayに送ることを実装しました。

miyohide.hatenablog.com

ただ本番環境においてはトレースだけでは足りず、リクエスト数やJVMの状態などさまざまな情報が必要になります。App Runnerにおいては、リクエスト数などは特に何もしなくてもメトリックスタブから参照できます。

今回はJVMなどの各種情報をCloudWatchに送信するようにしてみます。

前提

今回の検証では以下のバージョンを使いました。

  • Java 21
  • Gradle 8.5
  • Spring Boot 3.2.2
  • Jib 3.4.0
  • AWS OpenTelemetry Agent 1.32.0

ライブラリの選定

Spring関連プロジェクトにて、AWSのマネージドサービスを扱うためのライブラリとしてSpring Cloud AWSというものがあります。

awspring.io

今回はこのSpring Cloud AWSを使います。

Spring Cloud AWSはSpring BootやSpring Frameworkのバージョンに応じて使用するバージョンが異なります。詳細は以下GitHubに記載があるので確認します。

github.com

今回はSpring Boot 3.2.2を使っているので、Spring Cloud AWS 3.1.xを使います。

実装

build.gradleでの実装方法はSpring Cloud AWSのドキュメントに書いている通りに従います。

docs.awspring.io

CloudWatchにメトリックスを送信するためには下記ドキュメントの通りio.micrometer:micrometer-registry-cloudwatch2も必要となります。

docs.awspring.io

具体的な実装は以下の通り。

// 省略
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-actuator'
    // Spring Cloud AWSを使用するための記述 ここから
    implementation platform("io.awspring.cloud:spring-cloud-aws-dependencies:3.1.0")
    implementation 'io.awspring.cloud:spring-cloud-aws-starter'
    implementation 'io.micrometer:micrometer-registry-cloudwatch2'
    // Spring Cloud AWSを使用するための記述 ここまで
    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    javaAgent('software.amazon.opentelemetry:aws-opentelemetry-agent:1.32.0')
}

CloudWatchにメトリックスを送信するためには以下のドキュメントを参考にしながらapplication.propertiesに設定を記述します。

docs.awspring.io

今回は以下のように記述しました。

management.cloudwatch.metrics.export.enabled=true
management.cloudwatch.metrics.export.namespace=app/micrometer

なお、ネット上ではSpring Cloud AWS 2.xの情報が目につくのですが、Spring Cloud AWS 2.xと3.xにて幾らか変更点があるようです。以下のMigration Guideを確認すると良いかと思われます。

docs.awspring.io

AWSの設定

AWS App RunnerからCloudWatchにメトリックスを送信するためには、cloudwatch:PutMetricData権限が必要となります。今回、AWS App Runnerに付与しているIAMロールにインラインポリシーにて追加しました。

動作

以上の内容で各種メトリックスがCloudWatchに送信されます。「カスタム名前空間」にmanagement.cloudwatch.metrics.export.namespaceで設定していた値のものが作られていることが確認できます。

中身を確認すると、いろいろな情報が送信されています。

Javaアプリケーションに欠かせないヒープなどの情報は「area,id」のところにでていました。

GCの情報などは「action,cause,gc」のところにありました。

考察

ライブラリと少しの設定で各種メトリックスをCloudWatchに送信できるのは非常に有用です。何かトラブルが発生した時に情報が足りないとトラブル解決ができなくなることもあるので、設定しておいて損はないかと考えます。

一方で、CloudWatchは無料で使えるわけではないです。

aws.amazon.com

料金を踏まえて、取るメトリックを制限したい場合はapplication.propertiesに以下の記述をします。

# いったん全てのメトリックスの送信を止める
management.metrics.enable.all=false
# JVM関連だけを送信する
management.metrics.enable.jvm=true

また、Spring Cloud AWSの設定が間違っていてもSpring Bootアプリケーション自身は正常に動くのも注意が必要です。正常に動いているのでメトリックスも取れているだろうと思い込まずに実際に画面を見た方が良いと考えます。