DatadogでStep Functionsのログを確認してみた

# 背景・目的
以前、下記でカスタムモニタリングを試してみました。今回はDataDogのインテグレーション機能を利用してStep Functionsをモニタリングします。

https://qiita.com/zumax/items/989ed9f48f69791a1c03

# 実践
## 事前準備
### Datadog Integrationsの準備
https://docs.datadoghq.com/ja/getting_started/integrations/aws/

1. DataDogにサインインします
1. ナビゲーションペインで、「Integrations」をクリックします
1. ① 「AWS」で検索し、②「Amazon Web Services」をクリックします
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/faab0efd-6b77-4d6f-a814-84a45153bf8f.png" width=400 />

1. 「Add AWS Account」をクリックします
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/2f4ca5c8-c795-43fe-a3d3-3a7ff206cea4.png" width=300 />

1. 下記を入力し、「Launch CloudFormation Template」をクリックします
    - Automatically using CloudFormation
    - ①：AWSのリージョン：ap-northast-1
    - ②：Add Datadog API Key：API KEYを指定します
    - ③ Send AWS Logs to Datadog：Yes
    - ④ Detect security issues：今回はNo
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/98a508f4-c041-49b9-8315-7d9d858c789f.png)

1. AWSのCloudFormationが開きます
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/31fc943d-d32c-4cda-bae2-a94c36670455.png" width=300 />

1. 「スタックの作成」をクリックします
1. 完了すると、いくつかスタックが含まれています事がわかります
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/704df700-992f-4a36-b697-70dcc4576e5e.png)

### Datadog
1. Installedになりました
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/3abe0759-0f2c-46d4-931b-9068d905a290.png)


### IAMロールを修正
1. AWSにサインインします
1. CloudFormationに移動します
1. DatadogIntegration-DatadogIntegrationRoleStackを選択します
1. テンプレートタブをクリックします
1. 「Infrastructure Composerで表示」をクリックします
1. 「テンプレート」をクリックします
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/0e282c2c-4ef3-4c00-8c6f-fe962c1c6857.png)
1. `DatadogAWSIntegrationPolicy`に下記を追加します
    ```yml
    states:ListStateMachines,
    states:DescribeStateMachine
    ```
1. 「テンプレートを更新」をクリックします
1. 更新します


### VPCの作成
AWS Batchを動かすためにVPCを作成します

1. AWSにサインインします
1. VPCに移動します
1. VPCを作成をクリックします
1. 下記の要領で作成します
    - パブリックサブネット
    - プライベートサブネット
    - NAT GW


## アプリケーションの作成
### AWS Batch用コードの準備

1. 下記のシンプルなコードを作成します
    ```py
    import time
    import os
    
    print("Job started.")
    time.sleep(10)
    print("Job completed.")
    ```

1. Dockerfileを作成します
    ```bash
    FROM python:3.11-slim
    COPY job.py /app/job.py
    WORKDIR /app
    CMD ["python", "job.py"]
    ```

1. Dockerデーモンを起動するため、colimaを実行します
    ```bash
    colima start
    ```

1. ビルドします
    ```bash
    docker build -t my-batch-job .

    % docker images my-batch-job
    REPOSITORY     TAG       IMAGE ID       CREATED              SIZE
    my-batch-job   latest    XXXXX   About a minute ago   130MB
    % 
    ```

1. ローカルで動作確認してみます。動作しました
    ```bash
    % docker run -it my-batch-job      
    Job started.
    Job completed.
    %
    ```


### イメージの準備
1. ECRリポジトリを作成します
    ```json
    % aws ecr create-repository --repository-name my-batch-job
    {
        "repository": {
            "repositoryArn": "arn:aws:ecr:ap-northeast-1:XXXXX:repository/my-batch-job",
            "registryId": "XXXXX",
            "repositoryName": "my-batch-job",
            "repositoryUri": "XXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/my-batch-job",
            "createdAt": "2025-03-20T17:09:03.320000+09:00",
            "imageTagMutability": "MUTABLE",
            "imageScanningConfiguration": {
                "scanOnPush": false
            },
            "encryptionConfiguration": {
                "encryptionType": "AES256"
            }
        }
    }
    % 
    ```
1. ECRにログインします
    ```bash
    $ aws ecr get-login-password | docker login --username AWS --password-stdin <account_id>.dkr.ecr.<region>.amazonaws.com
    Login Succeeded
    ```

1. タグ付けします
    ```bash
    % docker tag my-batch-job:latest <account_id>.dkr.ecr.ap-northeast-1.amazonaws.com/my-batch-job:latest
    % docker images <account_id>.dkr.ecr.ap-northeast-1.amazonaws.com/my-batch-job
    REPOSITORY                                                       TAG       IMAGE ID       CREATED          SIZE
    <account_id>.dkr.ecr.ap-northeast-1.amazonaws.com/my-batch-job   latest    XXXXXX   13 minutes ago   130MB
    % 
    ```
    
1. ECRにプッシュします
    ```bash
    % docker push <account_id>.dkr.ecr.ap-northeast-1.amazonaws.com/my-batch-job:latest
    The push refers to repository [<account_id>.dkr.ecr.ap-northeast-1.amazonaws.com/my-batch-job]
    ・・・・
    latest: digest: sha256:XXXXXX size: 1366
    % 
    ```

1. ECRでも確認できました
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/05467409-966f-48ef-afdd-d927772e2480.png)

## AWS Batch
AWS Batchを作成します。

1. AWS Batchに移動します

### コンピューティング環境
1. ナビゲーションペインで「コンピューティング環境」をクリックします
1. 「作成」をクリックします
1. 下記を指定し、「次へ」をクリックします
    - コンピューティングタイプ：EC2
    - オーケストレーション：マネージド型
    - 名前：任意
    - サービスロール：デフォルト
    - インスタンスロール：新しいロールの作成
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/07364196-b040-4575-9dd5-09b5477a94df.png)
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/f94a461d-f176-4fb1-8d7a-f725cd2ee0c0.png)
1. EC2スポットインスタンス等の設定をし、「次へ」をクリックします
1. 作成したVPC、サブネットを選択し、「次へ」をクリックします
1. 「コンピューティング環境を作成」をクリックします
1. できました
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/71befff2-da84-446e-bab4-433952763297.png)


### ジョブキュー
1. ナビゲーションペインで「ジョブキュー」をクリックします
1. 「作成」をクリックします
1. 下記を指定し、「ジョブキューの作成」をクリックします
    - 名前：任意
    - 優先度：高いほど優先度高い
    - コンピューティング環境：上記で作成した環境
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/40811e56-1048-4db3-aa4f-ade84ef54e2a.png)

1. できました
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/6b843b1c-968e-4499-8ac6-a0144aad8028.png)

### ジョブ定義
1. ナビゲーションペインで「ジョブ定義」をクリックします
1. 「作成」をクリックします
1. 下記を指定し、「次へ」をクリックします
    - オーケストレーションタイプ：EC2
    - 全般
        - 名前：任意
        - 実行タイムアウト：300秒
        - スケジュールの優先度：1
        - ジョブの試行：1

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/6dbe0f17-efc9-4584-b0b6-4c75ecb3e1c0.png)
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/a9a96879-f918-4eba-9aef-515edf794e21.png)

1. コンテナ設定では、作成したECRを指定し「次へ」をクリックします
1. Linnuxとロギングの設定を「次へ」をクリックします
1. 「ジョブ定義を作成」をクリックします


## AWS Step Functions
AWS Batchを呼び出す、Step Functionsを作成します。

1. AWS Step Functionsに移動します

### ステートマシンの作成
1. 「ステートマシンの作成」をクリックします
1. ステートマシン名を指定し、「続行」します
1. 下記のコードを指定し、「作成」をクリックします
    ```json
    {
      "Comment": "sample statement",
      "StartAt": "SubmitBatchJob",
      "States": {
        "SubmitBatchJob": {
          "Type": "Task",
          "Resource": "arn:aws:states:::batch:submitJob.sync",
          "Arguments": {
            "JobName": "sample-job",
            "JobDefinition": "arn:aws:batch:ap-northeast-1:XXXXXX:job-definition/my-job-definition:1",
            "JobQueue": "arn:aws:batch:ap-northeast-1:XXXXXX:job-queue/my-batch-queue"
          },
          "End": true
        }
      },
      "QueryLanguage": "JSONata"
    }
    ```

1. ロールの作成で「確認」をクリックします
1. できました

### テスト
上記で作成したステートメントを実行してみます

1. 作成したステートメントを選択し、「実行を開始」をクリックします
1. 成功しました
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/0257d118-73bd-4cc0-9314-e8f9038e5af7.png)

1. CloudWatch Logsにもログが記録されました
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/10704894-aa48-447b-a5f5-746d22e44291.png)


## Step Functions（Batch）とDatadogを統合
### Step Functionsの設定変更
Step FunctionsでCloudWatch Logsにログを出力するように設定します。

#### IAMロール
デフォルトで作成されたIAMロールにはCloudWatch Logsへのログ出力ポリシーが含まれていないため、修正します。

https://docs.aws.amazon.com/ja_jp/step-functions/latest/dg/cw-logs.html


1. IAMロールに移動します
1. 該当のロールにアタッチされているIAMポリシーに、下記のポリシーを追加します
    ```json
    {
        "Effect": "Allow",
        "Action": [
            "logs:CreateLogDelivery",
            "logs:GetLogDelivery",
            "logs:UpdateLogDelivery",
            "logs:DeleteLogDelivery",
            "logs:ListLogDeliveries",
            "logs:PutResourcePolicy",
            "logs:DescribeResourcePolicies",
            "logs:DescribeLogGroups",
            "logs:CreateLogGroup",
            "logs:CreateLogStream",
            "logs:PutLogEvents"
        ],
        "Resource": "*"
    }
    ```

#### Step Functions

1. Step Functionsに移動します
1. 対象のステートマシンを選択します
1. 「ステートマシンの編集」をクリックします
1. 「設定」タブをクリックします
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/5f96a31e-3fd9-435e-9dc1-1cbd5ab75584.png)

1. ログ記録でログレベルに「ALL」を指定し、「保存」をクリックします
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/b6862bcb-49e6-4d97-8f7f-7ff5e0fa7728.png)

### DataDogの準備
DataDogの設定を確認しておきます。
1. Datadogにサインインします

#### AWS Integration 設定確認
1. ナビゲーションペインで、「Integrations」をクリックします
1. 「Amazon Web Services」をクリックします
1. 「Metric Collection」タブをクリックし、「Step Functions」を検索します
1. 有効になっている事がわかります
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/0ddb94f1-c195-4f18-9e9a-9ef544563f47.png)



### Datadog Forwarderのセットアップ
https://docs.datadoghq.com/ja/logs/guide/send-aws-services-logs-with-the-datadog-lambda-function/?tab=cloudformation

https://docs.datadoghq.com/ja/logs/guide/forwarder/?tab=cloudformation

#### API KEYの準備
DatadogのAPI KEYを取得します

1. ナビゲーションペインで、「アカウント」＞「API Keys」をクリックします
1. API Keysをコピーします

#### Lambdaのセットアップ
1. [こちら](https://docs.datadoghq.com/ja/logs/guide/forwarder/?tab=cloudformation)のページで、「Launch Stack」をクリックします

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/b361a2e6-9f61-4517-93bb-6dd2444a4562.png)

1. 下記を入力し、「スタックの作成」をクリックします
    - ①：DdApiKey：上記のAPI Key
    - ②：DdSite：東京のエンドポイント（ap1.datadoghq.com）を指定
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/43bee6d6-04c7-47e9-95b3-bedafcdacc01.png)

1. 作成されました
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/c822782d-d80c-418a-9693-214aa78853e0.png)

1. Lambdaも作成されています
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/319cc6c5-95aa-4b92-8d05-0c791946d22f.png)

### CloudWatchのサブスクリプションフィルターの設定
#### サブスクリプションの設定
1. CloudWatchに移動します
1. ナビゲーションペインの「ロググループ」をクリックします
1. 対象のロググループを選択します
1. ①「サブスクリプションフィルター」＞②「Lambdaサブスクリプションフィルターを作成」をクリックします
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/622612c4-2d2c-499d-9ae8-75a7f944a152.png" width=400/>



1. 下記を指定します
    - ①：Lambda関数：作成したLambda
    - ②：ログの形式：その他
    - ③：サブスクリプションフィルター名：任意
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/bd3d872e-b53d-4b53-9ee9-2309a452d78b.png)

1. 「パターンをテスト」をクリックすると出力イメージがわかります
1. 「ストリーミングを開始」をクリックすると、作成されます

#### ログイベントの作成
1. 対象のCloudWatch Logsを選択します
1. 「ログストリームを作成」をクリックします
1. ログストリーム名を入力し、「Create」をクリックします
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/29d29486-9ddf-48b3-88ad-534906a48a8d.png" width=300 />

1. 作成したログストリームをクリックします
1. 「ログイベントの作成」をクリックします
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/035f7d59-de42-4e8b-a257-98c5a76233a9.png)
1. メッセージを入力し、「作成」をクリックします
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/26e01581-c1d4-4c69-8108-f0596095835e.png)
1. 表示されました
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/101051c3-1f73-4654-aa95-146d93a539a4.png)

#### Logsで確認

1. ナビゲーションペインで、「Logs」をクリックします
1. 「Get Started」をクリックします
1. 「Cloud」をクリックします
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/43191661-030d-4b85-96f0-a51c583783f0.png" width=200 />

1. 「AWS」、「CloudFormation」、最後に「Explore Your Logs」をクリックします
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/6a471915-d9d9-4a23-a373-513e27759815.png)

1. テストで入力したイベント（ログ）が表示されました
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/62c0fd62-0937-42af-9931-d8931e365d4e.png)

#### Step Functionsを実行し、Datadogで確認する
1. Step Functionsに移動します
1. ナビゲーションペインで、「ステートマシン」をクリックします
1. 対象のステートマシンをクリックします
1. 「実行を開始」をクリックします
1. 完了しました
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/e775bf5a-a4c5-41e4-a772-721febd20d1c.png)

1. CloudWatch Logsを確認します。出力さていました
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/f5f1bcec-85ac-4879-a092-d69c81d017d5.png)

1. Datadogを確認します
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/ea9da87d-d9dd-4f18-b31d-ecc46bf0c60a.png)

# 考察
今回、下記を試してみました。次回は実行ステータスを可視化してみたいと思います。

- Step FunctionsのログをCloudWatch Logsへ出力
- CloudWatch Logsにサブスクリプションフィルターを設定
- Datadogで確認


# 参考
https://docs.datadoghq.com/integrations/amazon_web_services/

https://docs.datadoghq.com/serverless/step_functions/


https://docs.datadoghq.com/ja/integrations/amazon_step_functions/

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-get-template.html

https://qiita.com/zumax/items/d8a1fad9aa56d7c02ddd

https://docs.aws.amazon.com/ja_jp/step-functions/latest/dg/cw-logs.html

https://dev.classmethod.jp/articles/cloudwatchlog-forward-datadog/