Spring Boot 3.x アップデート時の micrometer-registry-cloudwatch のハマりポイント

この記事では、Spring Boot 2.7.x 系で既に micrometer-regstry-cloudwatch を使ったことある人向けのアップデート注意点をまとめました。はじめて導入する方は公式などをご参照ください。この記事にまとめた通り、バージョンによって設定が大きく異なるため利用バージョンをよく確認してから利用すると良いでしょう

## micrometer-registry-cloudwatch とは
https://micrometer.io/
micrometer (JVM アプリケーションでメトリクスを収集するライブラリ) から、AWS CloudWatch にメトリクスを送信するライブラリです。

## はじめに結論
+ 依存ライブラリ、設定ファイルを以下のように置き換えましょう。gradle, application.yaml想定のため、maven, application.properties などを使っている方は適宜読み替えてください

```diff_groovy:build.gradle
  plugins {
      id 'java'
-     id 'org.springframework.boot' version '2.7.13'
+     id 'org.springframework.boot' version '3.2.0'
      id 'io.spring.dependency-management' version '1.1.4'
  }

  dependencies {
      implementation "org.springframework.boot:spring-boot-starter-web"
      implementation "org.springframework.boot:spring-boot-starter-actuator"
-     implementation "io.awspring.cloud:spring-cloud-starter-aws:2.4.4"
-     implementation "io.awspring.cloud:spring-cloud-aws-context:2.4.4"
+     implementation 'io.awspring.cloud:spring-cloud-aws-starter-metrics:3.1.0'

-     implementation "io.micrometer:micrometer-registry-cloudwatch"
+     implementation "io.micrometer:micrometer-registry-cloudwatch2"
  }
```

```diff_yaml:application.yaml
- cloud:
-   aws:
-     stack:
-       auto: false
-     region:
-       auto: false
-       static: ap-northeast-1
  spring:
+   cloud:
+     aws:
+       region:
+         static: ap-northeast-1
  management:
-   metrics:
-     export:
-       cloudwatch:
+   cloudwatch:
+     metrics:
+       export:
          enabled: true
          namespace: app/Micrometer
```

+ 依存ライブラリや設定値が大きく変わっているので、ドキュメントを読んで移行先を確認しましょう。（dependabot任せでは無理）
+ 設定値に不備があってもアプリケーションは起動するのでメトリクスが取れているか CloudWatch 上で確認しましょう。（サーバが起動しても油断しないように）

ここから各変更点、ハマりポイントについて詳しく紹介していきます。

## ハマりポイント① 依存ライブラリの関係がわかりづらい
結論であげた依存ライブラリに、spring-boot-starter-actuator や awspring の spring-cloud-aws-starter などmicrometer以外のライブラリが存在します。 これらのライブラリの依存関係がわかりづらく、設定変更やエラー発生時の切り分けが困難なため、まずここから理解するのが大事です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182564/a9b49e6f-528c-ad1e-4e53-5ed9aca7f589.png)

それぞれの登場人物と依存関係について解説します。

### spring-boot-starter-actuator
名称の通り、spring-boot-actuator の starter ですが、Spring Boot と micrometer の橋渡し役も担っています。名前から役割が想像しづらいですね。

### micrometer-core/micrometer-observation
micrometer の本体です。Spring Boot 2.7 までは -core に依存していましたが、3.x からは-observation に依存するようになりました。spring-boot-starter-actuator の依存として入るので自分で指定せずにstarterに任せてしまうと良いでしょう。

### awspring
https://awspring.io/
Spring BootからAWS SDKを利用しやすくしてくれるライブラリです。micrometer-registry-cloudwatch から直接の依存はないため必須ではありませんが、[micromter公式](https://docs.micrometer.io/micrometer/reference/implementations/cloudwatch.html)でも紹介されている通り準公式的な位置付けとなるライブラリです。

### AWS SDK for Java
https://aws.amazon.com/jp/sdk-for-java/
JavaからAWSを利用するSDKです。v1とv2が存在し、それぞれに互換性はありません。v1/v2の選択方法については後述します。

## ハマりポイント② awspring のバージョンアップ
https://github.com/awspring/spring-cloud-aws?tab=readme-ov-file#compatibility-with-spring-project-versions

| Spring Cloud AWS            | Spring Cloud                                                                                                          | Spring Boot  | Spring Framework | AWS Java SDK |
|-----------------------------|-----------------------------------------------------------------------------------------------------------------------|--------------|------------------|--------------|
| 2.3.x (maintenance mode)  	 | [2020.0.x](https://github.com/spring-cloud/spring-cloud-release/wiki/Spring-Cloud-2020.0-Release-Notes) (3.0/Illford) | 2.4.x, 2.5.x | 5.3.x            | 1.x          |
| 2.4.x (maintenance mode)  	 | [2021.0.x](https://github.com/spring-cloud/spring-cloud-release/wiki/Spring-Cloud-2021.0-Release-Notes) (3.1/Jubilee) | 2.6.x, 2.7.x | 5.3.x            | 1.x          |
| 3.0.x                       | [2022.0.x](https://github.com/spring-cloud/spring-cloud-release/wiki/Spring-Cloud-2022.0-Release-Notes) (4.0/Kilburn) | 3.0.x, 3.1.x | 6.0.x            | 2.x          |
| 3.1.x                       | [2023.0.x](https://github.com/spring-cloud/spring-cloud-release/wiki/Spring-Cloud-2023.0-Release-Notes) (4.0/Kilburn) | 3.2.x        | 6.1.x            | 2.x          |

上記の通り、awspring は Spring Boot のバージョンに合わせてバージョンを選択する必要があります。Spring Boot 2.7.x -> 3.2 にバージョンアップする場合、awspirng は 2.4.x -> 3.1.x のバージョンアップが必要です。

ところが、spring-cloud-starter-aws は 2.4.4 までしか存在せず、3.1.x がありません。issueを追った感じでは、3.x を機にパッケージ分割をしたようです。今回は CloudWatch を使用したいので、spring-cloud-aws-starter-metrics を使用すればOKです。

```diff_groovy:build.gradle
dependencies {
-     implementation "io.awspring.cloud:spring-cloud-starter-aws:2.4.4"
-     implementation "io.awspring.cloud:spring-cloud-aws-context:2.4.4"
+     implementation 'io.awspring.cloud:spring-cloud-aws-starter-metrics:3.1.0'
    // ...
}
```

また設定値のパスが変わっているため合わせて対応が必要です。公式のmigrationガイドに一部記載があります（2023年12月現在WIP）
https://docs.awspring.io/spring-cloud-aws/docs/3.1.0/reference/html/index.html#migration-from-2-x-to-3-x

## ハマりポイント③ AWS SDK for Java のバージョンアップ
ポイント②であげたように、awspringを3.xにあげると AWS SDK for Java も 2.x にあげないといけません。しかし、micrometer-registry-cloudwatch は SDK v1 に依存するため、そのままでは動きません。SDK v2 対応の micrometer-registry-cloudwatch**2** があるのでそちらに切り替えが必要です。（そこで上げるのか・・・）

```diff_groovy:build.gradle
dependencies {
    // ...
-     implementation "io.micrometer:micrometer-registry-cloudwatch"
+     implementation "io.micrometer:micrometer-registry-cloudwatch2"
}
```

## ハマりポイント④ エラーが出ない
ここまでに依存ライブラリの変更や設定ファイル変更など、ハマりポイントを上げてきましたが、これらのポイントでミスをしても基本的にエラーが出ずアプリケーションは動作し続けます。
メトリクスのための設定ミスでアプリケーションが停止してしまっては本末転倒なので、ありがたい配慮ではあるのですが、ミスに気づきづらいのは辛いポイントです。
バージョンアップ後には、必ず CloudWatch 上でメトリクスが取れていることを確認しましょう。

## 終わりに
以上、　Spring Boot 3.x アップデート時の 　micrometer-registry-cloudwatch のハマりポイントでした。最終的な変更箇所自体はそれほど大きくなかった割に結構苦戦したので、同じ問題にハマった人の助けになれば幸いです。