[アップデート] Amazon CloudWatchでハイブリッド/マルチクラウドなメトリクス検索が可能になりました #AWSreinvent

2023.11.28

しばたです。

先日のアップデートでCloudWatch Metricsにおいて通常のメトリクス以外にオンプレ環境や他社クラウドをソースとしたメトリクス検索が可能になりました。

AWSからのアナウンスはこちらになります。

Jeff Barrによる解説ブログもありますのでこちらもご覧ください。

更新内容

更新内容自体はシンプルでCloudWatch Metricsでメトリクスを検索するデータソースを利用者が独自に定義できる様になりました。
本日時点では

  • Amazon OpenSearch
  • Amazon Prometheus
  • Amazon RDS for MySQL
  • Amazon RDS for PostgreSQL
  • Amazon S3 (CSVファイル)
  • Azure Monitor
  • Prometheus

をデータソースとして使用できます。
まだAWSサービスの比率が高いですが、Azure MonitorやPrometheusとAWS以外のデータソースもちゃんと用意されています。

内部実装

実装としてはLambda関数を使い独自のデータソースへアクセスしてCloudWatch Metricsのメトリクスデータを検索します。
AWSが提供するデータソースについては「AWS提供のLambda関数をCloudFormationでデプロイする」形となり、ユーザー独自のLambda関数を作ることも可能です。

料金

Jeff Barrのブログによれば

Pricing – There is no extra charge for the connectors. You pay for the invocations of the Lambda functions and for any other AWS infrastructure that you create.

とのことでLambda関数の実行に応じた料金がかかるとのことです。

ただ、この機能で検索したメトリクスが「カスタムメトリクス」として扱われるか否かについては明言されていませんでした。
予想ですが、本機能はあくまでも独自のデータソースからデータを検索してるだけなのでカスタムメトリクス扱いにはならない予感がします。
ただ、CloudWatchの各種API(GetMetricDataなど)は内部的に使われているのでその料金は別途かかるでしょう。

注意点

本機能のメインはあくまでも独自のデータソース定義+データ検索になり、検索するデータに時刻が含まれていることが前提となります。
(時系列データベースである必要はありませんが、時系列を持つデータである必要があります)

私は最初に「RDSのデータサイズ(データベースや表領域など)を収集するのに丁度良いのでは?」と考え、RDS for PostgreSQLのデータベースサイズを取得しようと

失敗例

SELECT CURRENT_TIMESTAMP, pg_database_size('postgres')

といったクエリを試すことにしたのですが、CURRENT_TIMESTAMPは常に現在時刻を返すため期待した結果にはなりませんでした。
この様な場合、定期的に別のテーブルに時刻とサイズを記録する必要があり以下の様な構造のデータが事前に必要となります。

記録時刻 サイズ
2023-11-28 00:00:00 100
2023-11-28 00:05:01 101
2023-11-28 00:10:02 101
2023-11-28 00:15:03 102
2023-11-28 00:20:04 101
2023-11-28 00:25:05 102
・・・後略・・・ ・・・

(時刻とその時点での値が継続して記録されていることが前提条件)

以前からある「Lambdaを使ってカスタムメトリクスを記録する」行為とは別物ですのでご注意ください。

試してみた

ここからは実際に試していきます。

今回は私の検証用AWSアカウントの東京リージョンを対象とし、RDS for PostgreSQLをデータソースにしてみます。
VPC等のネットワーク環境およびRDSインスタンスは事前に作成済みです。

データソースの作成

マネジメントコンソールからCloudWatch Metricsの画面を表示すると新たに「マルチソースクエリ」欄が増えています。

表示欄上部にある「データソース」から独自のデータソースを作成することができます。

データソースの作成ダイアログを開始し、今回は「Amazon RDS - PostgreSQL」選び次へ進みます。

続けて作成するデータソースの情報を埋めていきます。

LambdaからRDSインスタンスへのアクセスが発生するのでVPCを利用する形とし、予めLambda用のセキュリティグループを設定しておいてください。

データソースの作成を開始するとAWS提供のCloudFormationスタックが実行され、

  • パスワード保存のためのSecrets Managerシークレット
  • RDSへアクセスするためのLambda関数
  • Lambda用IAMロール+パーミッション
  • Lambda用CloudWatch Logsロググループ

が作成されます。

Lambda関数はこんな感じでNode.js 18のアプリケーションでした。

コードはMinifyされてる様で読めなくはないですが読み切るのはしんどいです。
ざっと見た感じDB識別子からDescribeDBInstancesを使ってDNS名を取得しSecrets Managerの認証情報を使って接続していました。
このためLambdaからインターネットアクセス可能にするか各種VPC Endpointを用意する必要があります。

クエリの実行

データソースを作成したあとはマルチソースクエリの一覧に追加され利用可能になります。

RDSの場合は以下の様な画面で接続するデータベースを選びSQLクエリを入力します。

「注意点」の節で触れた様に検索元データは時系列を持つデータである必要があります。
最初のSQLに少し手を加えて「5分前のデータが一件」という体のクエリをグラフ化するとこんな感じになります。  

5分前のデータが一件という体にするクエリ

SELECT CURRENT_TIMESTAMP - time '00:05' AS ctime, pg_database_size('postgres')

これで一応グラフにプロットするだけは出来ました。
(常に直近5分前の一点しか表示できないので意味はありませんが...)

グラフの定義はこんな感じでLAMBDA()という式を使いデータソースからのデータ検索を行う形になっていました。

ちなみにRDSの場合、時刻の列が無い時は全ての期間で同一値という扱いになるそうです。

時刻の列を取得しない場合

SELECT pg_database_size('postgres')

(全期間同一値の扱いになるためグラフは直線に)

しきい値の監視をするだけならこれで代用できそうです。

一応適当なデータを投入したTBL1テーブルで試した結果はこんな感じになります。
いい加減な値を入れてますが必要となるデータのイメージは掴んでいただけるかと。

データソースの削除

本日時点ではデータソース削除のためのUIは用意されていない様です。
CloudFormationスタックを削除して各種リソース削除してください。

CloudWatchの「設定」からデータソースの一覧を確認できるのですが、あくまで参照のみでした。

最後に

以上となります。

仕組み自体はシンプルであるため適用範囲は広そうです。
今後はより多くのデータソースが増えると思いますので期待して待ちましょう。