Spring Boot でプログラム内部のメトリクスを収集するときに使われるMicrometer。収集したメトリクスをどうやって活用するか(どのサービスで監視・グラフ化するか)考えた結果、AWS CloudWatchを使うことにした。
Prometheusは運用できない
監視といえば、Prometheus - Monitoring system & time series databaseがここ数年人気だ。
「差別化する必要がなければメジャーに乗っかれ」というポリシーで、Prometheusももちろん使ってみようとした。しかし、運用してくれるサービスが見当たらない。運用に関われるエンジニアが少ないので、監視関連に人的リソースを割くのは可能な限り避けたい。となると、残念ながらPrometheusは候補から外れる。普段であればMackerel(マカレル)を使うのだが、今回は1分よりも短い間隔でメトリクスを送信することも考えていたため、他の方法を検討することにした。
Mackerel(マカレル): 新世代のサーバー管理・監視サービス
はてなが開発した新世代のサーバー管理・監視サービスです。仮想サーバーなどクラウドサービスをMackerelで統合管理および監視ができます。フリートライアル実施中!
CloudWatch連携は可能なのか?
AWSで動いているプログラムのメトリクスの収集なので、CloudWatchを利用できないか検討するのが自然な流れだろう。ということでMicrometerのdocsを見てみたのだが、PrometheusはあってもCloudWatchはなかった。一方、micrometer/implementations at master · micrometer-metrics/micrometer · GitHubを覗いてみると、cloudwatchとcloudwatch2が存在しているものの、どう違うのかわからない。そもそも、docsに出てこない時点で注意が必要だ。
CloudWatch エージェントはStatsDプロトコルを使用できる
CloudWatchエージェントでは、StatsDプロトコルを用いてカスタムメトリクスを取得することができる。Micrometerのdocsを見ると、StatsDはサポートしているモニタリングシステムに含まれている。
micrometer+StatsD -> CloudWatch Agent -> CloudWatch
という構成で、Spring BootアプリケーションのメトリクスをCloudWatchに送信できることがわかった。
micrometer側(Spring Boot側)の設定は問題ないだろう。CloudWatchエージェントは自ホスト(localhost)で動かすので、自ホストにあるStatsDに向けてメトリクスを送信するようにすればOK。
となると、CloudWatchエージェントの設定をどうするか。
ググってみると、CloudWatchAgentのStatsDを試してみる - Qiitaという記事が見つかった。
CloudWatchAgentのStatsDを試してみる - Qiita
CloudWatchAgentを設定をしていると、statsDとかcollectdとか名前が出てきますが、どうやらOSSの数値レポーティングツールらしいです。 prometheusを主に使っているので困ったことがなくて所見ですが、今...
/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.jsonに行う。 パラメータについては、StatsD を使用したカスタムメトリクスの取得 - Amazon CloudWatchを参照。説明が多いが、上記サンプルの項目を確認すれば十分だ。メトリクスの取得間隔とCloudWatchへの送信間隔の設定もある。
直接CloudWatchに送れるのは嬉しい
CloudWatchエージェントが必要とはいえ、他のサービスを経由せずにCloudWatchにメトリクスを送れるのは便利だ。イベントブリッジを使えば外部サービスからCloudWatchにイベントを送信することができるが、利用サービスが多い=障害ポイントが多い という認識なので、AWSに直接送れるというのはメリットだ。 また、CloudWatchに送れば、AutoScalingやLambdaの起動など、AWSの持っている仕組みをスムーズに使うことができる。CloudWatchはデータのグラフ化が弱いという印象だが、それも改善されるだろう。
CPU利用率やディスクの空き容量などのインフラ側のメトリクスはよく収集されるが、プログラム内部のメトリクス、例えば、外部API呼び出しの時間や受け付けたHTTPリクエストの数などは、あまり収集されていないという印象だ。Micrometerを使えば送信先のサービスはjarを入れ替えるだけで済むので、もっと内部のメトリクスを収集するような流れになってほしい。