Step Functions(ステートマシン)が出力するCloudWatchメトリクスを確認してみた

こんにちは、坂巻です。

今回はStep FunctionsのCloudWatchメトリクスに関するエントリです。

ステートマシンがエラーになった際の、CloudWatchアラームを作成したくて、 ステートマシンが出力するメトリクスを確認したので、そのアウトプットとなります。

Step Functionsが出力するメトリクスは以下に記載があります。

確認した背景である、ステートマシンの結果通知(異常系のみ)を目的としているため、 意図的にエラー等を発生させ、何のメトリクスが出力されるか確認してみたいと思います。 なお、確認するメトリクスは、ステートマシンのメトリクスにしぼっています。

ステートマシンのメトリクス

ステートマシンでは、次のメトリクスが使用できます。

メトリクス 説明
ExecutionTime 実行の開始時点から終了時点までの間隔 (ミリ秒単位)。
ExecutionThrottled 調整済みのStateEnteredイベントと再試行回数。
ExecutionsAborted 中断または終了された実行の数。
ExecutionsFailed 失敗した実行の数。
ExecutionsStarted 開始された実行の数。
ExecutionsSucceeded 正常に完了した実行の数。
ExecutionsTimedOut 何らかの理由でタイムアウトした実行の数。

詳細についてはこちらを確認してください。

動作確認

環境

ステートマシン(TestStateMachine)

タスクステートだけの、シンプルなステートマシンです。

1

Lambda(TestFunction)

Lambda関数もシンプルな「Hello World」のコードです。

import json
def lambda_handler(event, context):
    return {
        "statusCode": 200,
        "body": json.dumps('Hello from Lambda!')
    }

ステートマシンの定義や、Lambda関数のコードを更新しながら実施してみたいと思います。

正常終了

正常終了時の時に出力されるメトリクスについて確認したいと思います。 先に記載した環境でステートマシンを実行しました。

2

この状態でステートマシンを実行すると、実行結果は「成功」となりました。CloudWatchを確認してみたいと思います。 メトリクスの名前空間はAWS/Statesとなり、今回確認したいステートマシンのメトリクスはExecutionMetriceに含まれています。

3

該当のステートマシン(TestStateMachine)のメトリクスを確認してみます。

4

正常に完了した実行の数である、ExecutionsSucceededに値がセットされました。

例外

Lambda関数側で例外が発生した時に出力されるメトリクスについて確認したいと思います。 先に記載したLambda関数のコードを例外が発生するように更新しました。

import json
def lambda_handler(event, context):
    raise Exception
    return {
        "statusCode": 200,
        "body": json.dumps('Hello from Lambda!')
    }

この状態でステートマシンを実行すると、実行結果は「失敗」となりました。

5

CloudWatchを確認してみたいと思います。

6

失敗した実行の数である、ExecutionsFailedに値がセットされました。

なお、Lambda関数側で例外を捉えると、ステートマシン側に例外は渡されません。

import json
from time import sleep
def lambda_handler(event, context):
    try:
        raise Exception
    except Exception:
        return {
            "statusCode": 200,
            "body": json.dumps('Hello from Lambda!')
        }

14

Lambda関数、ステートマシンの双方で例外を処理したい場合は、ステートマシンにも例外を渡すようにしましょう。

import json
from time import sleep
def lambda_handler(event, context):
    try:
        raise Exception
    except Exception:
        raise Exception
        return {
            "statusCode": 200,
            "body": json.dumps('Hello from Lambda!')
        }

15

ステートマシン側の例外処理について以下を確認してください。

タイムアウト(Lambda)

Lambda関数がタイムアウトした時に出力されるメトリクスについて確認したいと思います。 Lambda関数のタイムアウトの設定を「3秒」にし、関数内で5分間待機するように更新しました。

import json
from time import sleep
def lambda_handler(event, context):
    sleep(300)
    return {
        "statusCode": 200,
        "body": json.dumps('Hello from Lambda!')
    }

この状態でステートマシンを実行すると、実行結果は「失敗」となりました。 Lambda側のタイムアウトは「例外」としてステートマシンに返されているようです。

7

CloudWatchを確認してみたいと思います。

8

失敗した実行の数である、ExecutionsFailedに値がセットされました。

タイムアウト(StepFunctions)

ステートマシンがタイムアウトした時に出力されるメトリクスについて確認したいと思います。 Lambda関数の設定は、先の設定(タイムアウト(Lambda))のままで、ステートマシンの定義を更新しました。

{
  "StartAt": "TestFunction",
  "TimeoutSeconds": 1,
  "States": {
    "TestFunction": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:ap-northeast-1:XXXXXXXXXXXX:function:TestFunction",
      "End": true
    }
  }
}

ステートマシンが開始され、1秒でタイムアウトが発生する設定です。 なお、タスクステートで使用できるフィールドについては、以下を確認してください。

この状態でステートマシンを実行すると、実行結果は「タイムアウト」となりました。

9

CloudWatchを確認してみたいと思います。

10

タイムアウトした実行の数である、ExecutionsTimedOutに値がセットされました。

中断

ステートマシンの実行を停止させた場合に出力されるメトリクスについて確認したいと思います。 ステートマシンは、先の定義からタイムアウトを除いた定義に更新しました。

{
  "StartAt": "TestFunction",
  "States": {
    "TestFunction": {
      "Type": "Task",
      "Resource": "arn:aws:lambda:ap-northeast-1:XXXXXXXXXXXX:function:TestFunction",
      "End": true
    }
  }
}

Lambda関数のコードは、先程(5分間待機)のままで、タイムアウト設定を5分に更新しました。 ステートマシン実行後、5分間は処理が実行されるので、手動でステートマシンを停止してみたいとおもいます。

11

実行結果は「中断」となりました。

12

CloudWatchを確認してみたいと思います。

13

中断または終了された実行の数である、ExecutionsAbortedに値がセットされました。

さいごに

確認する前は、例えばタイムアウトの場合、ExecutionsTimedOutと、ExecutionsFailedの両方でる?とも思いましたが、そんなことはありませんでした。 ステートマシン終了時に出力されるメトリクスは結果に応じて、ExecutionsAbortedExecutionsFailedExecutionsSucceededExecutionsTimedOutのいずれかが出力されるようです。システムの特性を考慮して、CloudWatchアラームが作成できそうです!