AWS Step FunctionsステートマシンからGetMetricData APIを使用してCloudWatch メトリクスのデータポイントを取得する(AWS CDK)

2021.12.21

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、CX事業本部 IoT事業部の若槻です。

今回は、AWS Step FunctionsステートマシンからGetMetricData APIを使用してCloudWatchメトリクスのデータポイントを取得する構成をAWS CDKで作成してみました。

GetMetricDataなら大規模かつ柔軟なデータ取得が可能

CloudWatchメトリクスのデータを取得するAPIには、GetMetricStatisticsGetMetricDataの2つがありますが、ベストプラクティスとされているのはGetMetricDataです。

以下のように両者を比べるとGetMetricData APIを使用した方が大規模かつ柔軟にメトリクスデータを取得できます。

1 コールあたりのメトリクス数 1 コールあたりのデータポイント数 Metric Mathのサポート 取得のページング
GetMetricData 500 100,800 あり あり
GetMetricStatistics 1 1,440 なし なし

今回はGetMetricData APIを使用してCloudWatchメトリクスのデータポイントを取得してみます。

やってみた

下記のCloudWatchメトリクスからデータポイントを取得してみます。

リソース作成

ステートマシンのリソースを次のAWS CDKスタックをデプロイして作成します。StartTimeEndTimeMetricDataQueriesは入力から取得するようにしています。

lib/aws-cdk-app-stack.ts

import * as cdk from '@aws-cdk/core';
import * as sfn from '@aws-cdk/aws-stepfunctions';
import * as tasks from '@aws-cdk/aws-stepfunctions-tasks';

export class AwsCdkAppStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const getMetricDataTask = new tasks.CallAwsService(
      this,
      'getMetricDataTask',
      {
        service: 'cloudwatch',
        action: 'getMetricData',
        parameters: {
          'StartTime.$': '$.startTime',
          'EndTime.$': '$.endTime',
          'MetricDataQueries.$': '$.metricDataQueries',
        },
        iamResources: ['*'],
        iamAction: 'cloudwatch:GetMetricData',
      }
    );

    new sfn.StateMachine(this, 'testStateMachine', {
      stateMachineName: 'testStateMachine',
      definition: getMetricDataTask,
    });
  }
}

cdk deployすると、次の定義のステートマシンが作成されます。

{
  "StartAt": "getMetricDataTask",
  "States": {
    "getMetricDataTask": {
      "End": true,
      "Type": "Task",
      "Resource": "arn:aws:states:::aws-sdk:cloudwatch:getMetricData",
      "Parameters": {
        "StartTime.$": "$.startTime",
        "EndTime.$": "$.endTime",
        "MetricDataQueries.$": "$.metricDataQueries"
      }
    }
  }
}

取得してみる

ステートマシンを実行してデータポイントを取得してみます。入力として下記を指定します。同じメトリクスに対して2つの異なる統計方法のリクエストを指定しています。

startTimeendTimeは取得対象のデータポイントの範囲です。MetricStatPeriodはメトリクスの統計期間、Statは統計方法を指定します。

{
  "startTime": "2021-12-21T14:00:00Z",
  "endTime": "2021-12-21T14:05:00Z",
  "metricDataQueries": [
    {
      "Id": "queryRequest01",
      "MetricStat": {
        "Metric": {
          "Namespace": "StateMachinePublish",
          "MetricName": "temperature",
          "Dimensions": [
            {
              "Name": "Site",
              "Value": "site_01"
            }
          ]
        },
        "Period": 60,
        "Stat": "Maximum"
      }
    },
    {
      "Id": "queryRequest02",
      "MetricStat": {
        "Metric": {
          "Namespace": "StateMachinePublish",
          "MetricName": "temperature",
          "Dimensions": [
            {
              "Name": "Site",
              "Value": "site_01"
            }
          ]
        },
        "Period": 120,
        "Stat": "Average"
      }
    }
  ]
}

実行が成功しました。

実行結果(ExecutionSucceeded)は次のようになりました。MetricDataResultsでクエリごとの結果が取得できています。

{
  "output": {
    "Messages": [],
    "MetricDataResults": [
      {
        "Id": "queryRequest01",
        "Label": "temperature Maximum 60",
        "StatusCode": "Complete",
        "Timestamps": [
          "2021-12-21T14:04:00Z",
          "2021-12-21T14:03:00Z",
          "2021-12-21T14:02:00Z",
          "2021-12-21T14:01:00Z",
          "2021-12-21T14:00:00Z"
        ],
        "Values": [
          22,
          17,
          0,
          28,
          23
        ]
      },
      {
        "Id": "queryRequest02",
        "Label": "temperature Average 120",
        "StatusCode": "Complete",
        "Timestamps": [
          "2021-12-21T14:04:00Z",
          "2021-12-21T14:02:00Z",
          "2021-12-21T14:00:00Z"
        ],
        "Values": [
          22,
          8.5,
          25.5
        ]
      }
    ]
  },
  "outputDetails": {
    "truncated": false
  }
}

おわりに

AWS Step FunctionsステートマシンからgetMetricData APIを使用してCloudWatchメトリクスのデータポイントを取得する構成をAWS CDKで作成してみました。

複数のメトリクスからデータをステートマシンで取得する必要があったのですが、GetMetricData APIを使うことにより一回のAPIコールで取れる構成とすることができました。これがGetMetricStatistics APIならメトリクスごとにMapステート内で繰り返しコールする必要があったので、より効率的な方法を見つけられて良かったです。

参考

以上