Amazon EventBridgeのログ出力機能でAPI DestinationやLambda関数の実行時エラーをログ出力できるか確認してみた

Amazon EventBridgeのログ出力機能でAPI DestinationやLambda関数の実行時エラーをログ出力できるか確認してみた

特にAPI Destinationのトラブルシューティングが捗りそう
2025.07.24

AWSのAPIコール以外でもエラー時のログを出力してくれるのか気になる

こんにちは、のんピ(@non____97)です。

皆さんはAmazon EventBridgeのログ出力機能がAWSのAPIコール以外でもエラー時のログを出力してくれるのか気になったことはありますか? 私はあります。

先日Amazon EventBridgeのEvent Busでログ出力設定ができるようになったアップデートを紹介しました。

https://dev.classmethod.jp/articles/amazon-eventbridge-enhanced-logging-improved-observability/

これにより、以下のようなログを記録できるようになりました。

  • Event Busでイベントの受信が成功/失敗した
  • イベントがEventBridge Ruleのイベントパターンにマッチした/していない
  • ターゲットの呼び出しが成功/失敗した

上述の記事では実際にターゲットとして指定したCloudWatch Logsロググループに正常に書き込みが行えたかどうか確認した訳ですが、AWSのAPIコール以外でも同様にログ出力されるかどうか気になりました。

最近ではEvntBridge API DestionationとInput Transformeterを用いて、あるイベントをトリガーに外部のAPIにアクセスすることも多いでしょう。

https://dev.classmethod.jp/articles/event-bridge-api-destinations-with-slack/

従来、APIリクエスト先が異なる場合やリクエストBODYが正常な値ではない場合についてはトラブルシューティングに時間がかかりがちでした。

また、Lambda関数やStep Functionsのステートマシンの実行時エラーについても気になります。

EventBridge RuleからLambda関数やStep Functionsステートマシンを呼び出す際は非同期実行になります。

EventBridge にイベントを多数の AWS サービスリソースに送信させることができます。具体的には次のとおりです。

  • API Gateway
  • AWS AppSync
  • バッチジョブのキュー
  • CloudWatch ロググループ
  • CodeBuild プロジェクト
  • CodePipeline
  • Amazon EBS CreateSnapshot API コール
  • EC2 イメージビルダー
  • EC2 RebootInstances API コール
  • EC2 StopInstances API コール
  • EC2 TerminateInstances API コール
  • ECS タスク
  • Firehose 配信ストリーム
  • Glue ワークフロー
  • Incident Manager レスポンスプラン
  • Inspector 評価テンプレート
  • Kinesis ストリーミング
  • Lambda 関数 (ASYNC)
  • Amazon Redshift クラスターデータ API クエリ
  • Amazon Redshift Serverless ワークグループデータ API クエリ
  • SageMaker AI パイプライン
  • Amazon SNS トピック
  • Amazon SQS キューと FIFO キュー
  • Step Functions ステートマシン (ASYNC)
  • Systems Manager Automation
  • Systems Manager OpsItem
  • Systems Manager Run Command

Amazon EventBridge のイベントバスターゲット - Amazon EventBridge

EventBridge Rule的にはターゲットを呼び出すまでが責務なのであれば、正常に呼び出したLambda関数内で発生したエラーについては感知しないように思えます。

実際に確認してみました。

いきなりまとめ

  • EventBridge API Destinationの実行時エラーをログ出力することが可能
  • Lambda関数やStep Functinnsステートマシンでは実行時エラーをログ出力することはできない
  • エラー時にログを出力するかは各ターゲットごとに事前検証した方が良さそう

EventBridge API Destination編

Webhook URLが正しくない場合

まず、EventBridge API Destionation編です。

以下環境で用意したリソースをそのまま再利用します。

https://dev.classmethod.jp/articles/aws-cdk-eventbridge-api-destination-google-chat-cloudwatch-alarm-notification/

API Destionationで定義しているWebhook URLのtoken末尾にDosukoiWasshoiを付与します。

1.API 送信先を編集.png

defaultのEvent BusのログレベルをERRORにして、CloudWatch Logsに出力するように設定します。
2.defaultのEvent Busのログレベル.png

この状態で適当にEC2インスタンスにタグを付与して、CloudWatch Alarmがアラーム状態となり、EventBridge Ruleでトリガーするようにします。

出力先のロググループを確認すると、以下のようなログが出力されていました。

{
    "resource_arn": "arn:aws:events:us-east-1:<AWSアカウントID>:event-bus/default",
    "message_timestamp_ms": 1753279232106,
    "event_bus_name": "default",
    "request_id": "861770af-d703-45bf-a88a-3058cce11b54",
    "event_id": "73104166-0a40-4c92-3379-a0ed7b4b0609",
    "invocation_id": "73104166-0a40-4c92-3379-a0ed7b4b0609_1ed3393b-cb79-57aa-67b1-3226ab097895",
    "message_type": "INVOCATION_ATTEMPT_PERMANENT_FAILURE",
    "log_level": "ERROR",
    "details": {
        "rule_arn": "arn:aws:events:us-east-1:<AWSアカウントID>:rule/GoogleChatAwsNotification-NotificationConstructRule-eyR5rsqDuIp0",
        "role_arn": "arn:aws:iam::<AWSアカウントID>:role/GoogleChatAwsNotification-NotificationConstructRole-KE4kuzUAsJe3",
        "target_arn": "arn:aws:events:us-east-1:<AWSアカウントID>:api-destination/NotificationConstructDestinationApiDestinationEDEEF-qxr7gZIj4H7b/102baef6-979b-4615-a2ef-0412ec89b175",
        "attempt_type": "FIRST",
        "attempt_count": 1,
        "invocation_status": "INVALID_PARAMETER",
        "target_duration_ms": 503,
        "target_response_body": "{\n  \"error\": {\n    \"code\": 400,\n    \"message\": \"Missing or malformed token in the request. The token can be obtained from incoming webhook configuration screen.\",\n    \"status\": \"INVALID_ARGUMENT\"\n  }\n}\n",
        "http_status_code": 400
    },
    "error": {
        "http_status_code": 400,
        "error_message": "ApiDestination returned HTTP status 400 with payload: {\n  \"error\": {\n    \"code\": 400,\n    \"message\": \"Missing or malformed token in the request. The token can be obtained from incoming webhook configuration screen.\",\n    \"status\": \"INVALID_ARGUMENT\"\n  }\n}\n"
    }
}
{
    "resource_arn": "arn:aws:events:us-east-1:<AWSアカウントID>:event-bus/default",
    "message_timestamp_ms": 1753279232109,
    "event_bus_name": "default",
    "request_id": "861770af-d703-45bf-a88a-3058cce11b54",
    "event_id": "73104166-0a40-4c92-3379-a0ed7b4b0609",
    "invocation_id": "73104166-0a40-4c92-3379-a0ed7b4b0609_1ed3393b-cb79-57aa-67b1-3226ab097895",
    "message_type": "INVOCATION_FAILURE",
    "log_level": "ERROR",
    "details": {
        "rule_arn": "arn:aws:events:us-east-1:<AWSアカウントID>:rule/GoogleChatAwsNotification-NotificationConstructRule-eyR5rsqDuIp0",
        "role_arn": "arn:aws:iam::<AWSアカウントID>:role/GoogleChatAwsNotification-NotificationConstructRole-KE4kuzUAsJe3",
        "target_arn": "arn:aws:events:us-east-1:<AWSアカウントID>:api-destination/NotificationConstructDestinationApiDestinationEDEEF-qxr7gZIj4H7b/102baef6-979b-4615-a2ef-0412ec89b175",
        "target_input": "{\"text\":\"👋🌎 こんにちは! AWSに関する通知だよ!!以下のメッセージを確認してね 🌎👋\",\"cards_v2\":[{\"card\":{\"header\":{\"title\":\"CloudWatch Alarm State Change\",\"image_url\":\"https://fonts.gstatic.com/s/i/short-term/release/googlesymbols/error/default/24px.svg\"},\"sections\":[{\"header\":\"<a href='https://us-east-1.console.aws.amazon.com/cloudwatch/home?region=us-east-1#alarmsV2:alarm/GoogleChatAwsNotificationStack-AlarmConstruct19D9277E-4sEB1Om9TpR4'>CloudWatchアラーム情報</a></a>\",\"widgets\":[{\"text_paragraph\":{\"text\":\"AWSアカウントID : <AWSアカウントID>\"}},{\"text_paragraph\":{\"text\":\"リージョン : us-east-1\"}},{\"text_paragraph\":{\"text\":\"CloudWatchアラーム名 : GoogleChatAwsNotificationStack-AlarmConstruct19D9277E-4sEB1Om9TpR4\"}},{\"text_paragraph\":{\"text\":\"CloudWatchアラームの説明 : これは何かタグが付与されたことを知らせるアラートです。\"}}]},{\"header\":\"現在の状態\",\"widgets\":[{\"text_paragraph\":{\"text\":\"状態 : ALARM\"}},{\"text_paragraph\":{\"text\":\"理由 : Threshold Crossed: 1 datapoint [1.0 (23/07/25 13:59:00)] was greater than or equal to the threshold (1.0).\"}},{\"text_paragraph\":{\"text\":\"時刻 : 2025-07-23T14:00:31.520+0000\"}}]},{\"header\":\"前回の状態\",\"widgets\":[{\"text_paragraph\":{\"text\":\"状態 : OK\"}},{\"text_paragraph\":{\"text\":\"理由 : Threshold Crossed: no datapoints were received for 1 period and 1 missing datapoint was treated as [NonBreaching].\"}},{\"text_paragraph\":{\"text\":\"時刻 : 2025-07-17T06:32:08.224+0000\"}}]}]}}]}",
        "target_properties": "{\"httpProperties\":{\"pathParameterValues\":[],\"headerParameters\":{},\"queryStringParameters\":{}}}",
        "total_attempts": 1,
        "final_invocation_status": "INVALID_PARAMETER",
        "ingestion_to_start_latency_ms": 50,
        "ingestion_to_complete_latency_ms": 554,
        "target_duration_ms": 503,
        "target_response_body": "{\n  \"error\": {\n    \"code\": 400,\n    \"message\": \"Missing or malformed token in the request. The token can be obtained from incoming webhook configuration screen.\",\n    \"status\": \"INVALID_ARGUMENT\"\n  }\n}\n",
        "http_status_code": 400
    },
    "error": {
        "http_status_code": 400,
        "error_message": "ApiDestination returned HTTP status 400 with payload: {\n  \"error\": {\n    \"code\": 400,\n    \"message\": \"Missing or malformed token in the request. The token can be obtained from incoming webhook configuration screen.\",\n    \"status\": \"INVALID_ARGUMENT\"\n  }\n}\n"
    }
}

Missing or malformed token in the request. The token can be obtained from incoming webhook configuration screen.と分かりやすいエラーメッセージも出力されていますね。これはありがたい。

リクエストBODYが正しくない場合

続いて、リクエストBODYが正しくない場合を確認します。

Input Transformerのテンプレートはもともと以下のとおりです。

before
{
  "text": "👋🌎 こんにちは! AWSに関する通知だよ!!以下のメッセージを確認してね 🌎👋",
  "cards_v2": [
    {
      "card": {
        "header": {
          "title": "CloudWatch Alarm State Change",
          "image_url": "https://fonts.gstatic.com/s/i/short-term/release/googlesymbols/error/default/24px.svg"
        },
        "sections": [
          {
            "header": "<a href='https://<region>.console.aws.amazon.com/cloudwatch/home?region=<region>#alarmsV2:alarm/<alarmName>'>CloudWatchアラーム情報</a></a>",
            "widgets": [
              {
                "text_paragraph": {
                  "text": "AWSアカウントID : <account>"
                }
              },
              {
                "text_paragraph": {
                  "text": "リージョン : <region>"
                }
              },
              {
                "text_paragraph": {
                  "text": "CloudWatchアラーム名 : <alarmName>"
                }
              },
              {
                "text_paragraph": {
                  "text": "CloudWatchアラームの説明 : <alarmDescription>"
                }
              }
            ]
          },
          {
            "header": "現在の状態",
            "widgets": [
              {
                "text_paragraph": {
                  "text": "状態 : <stateValue>"
                }
              },
              {
                "text_paragraph": {
                  "text": "理由 : <stateReason>"
                }
              },
              {
                "text_paragraph": {
                  "text": "時刻 : <stateTimestamp>"
                }
              }
            ]
          },
          {
            "header": "前回の状態",
            "widgets": [
              {
                "text_paragraph": {
                  "text": "状態 : <previousStateValue>"
                }
              },
              {
                "text_paragraph": {
                  "text": "理由 : <previousStateReason>"
                }
              },
              {
                "text_paragraph": {
                  "text": "時刻 : <previousStateTimestamp>"
                }
              }
            ]
          }
        ]
      }
    }
  ]
}

Input Transformerのテンプレートを以下のように存在しないキーを使用するように変更しました。

>  diff -u ./before.json ./after.json
--- ./before.json 2025-07-24 09:05:20
+++ ./after.json 2025-07-24 09:05:47
@@ -1,6 +1,6 @@
 {
   "text": "👋🌎 こんにちは! AWSに関する通知だよ!!以下のメッセージを確認してね 🌎👋",
-  "cards_v2": [
+  "cards_v234567890": [
     {
       "card": {
         "header": {

この状態でEventBridge Ruleが動作するようにEC2インスタンスにタグ付けを行います。

すると、Event Busで指定したCloudWatch Logsロググループに以下ログが出力されていました。

{
    "resource_arn": "arn:aws:events:us-east-1:<AWSアカウントID>:event-bus/default",
    "message_timestamp_ms": 1753281211849,
    "event_bus_name": "default",
    "request_id": "6cbc231c-c379-4168-88f4-9ddcf64612ab",
    "event_id": "5c93dd68-6982-1a51-142e-2ccc2d8e3d7e",
    "invocation_id": "5c93dd68-6982-1a51-142e-2ccc2d8e3d7e_3fe723ab-f67e-511f-439c-99fadcfb7be3",
    "message_type": "INVOCATION_ATTEMPT_PERMANENT_FAILURE",
    "log_level": "ERROR",
    "details": {
        "rule_arn": "arn:aws:events:us-east-1:<AWSアカウントID>:rule/GoogleChatAwsNotification-NotificationConstructRule-eyR5rsqDuIp0",
        "role_arn": "arn:aws:iam::<AWSアカウントID>:role/GoogleChatAwsNotification-NotificationConstructRole-KE4kuzUAsJe3",
        "target_arn": "arn:aws:events:us-east-1:<AWSアカウントID>:api-destination/NotificationConstructDestinationApiDestinationEDEEF-qxr7gZIj4H7b/102baef6-979b-4615-a2ef-0412ec89b175",
        "attempt_type": "FIRST",
        "attempt_count": 1,
        "invocation_status": "INVALID_PARAMETER",
        "target_duration_ms": 218,
        "target_response_body": "{\n  \"error\": {\n    \"code\": 400,\n    \"message\": \"Invalid JSON payload received. Unknown name \\\"cards_v234567890\\\" at 'message': Cannot find field.\",\n    \"status\": \"INVALID_ARGUMENT\",\n    \"details\": [\n      {\n        \"@type\": \"type.googleapis.com/google.rpc.BadRequest\",\n        \"fieldViolations\": [\n          {\n            \"field\": \"message\",\n            \"description\": \"Invalid JSON payload received. Unknown name \\\"cards_v234567890\\\" at 'message': Cannot find field.\"\n          }\n        ]\n      }\n    ]\n  }\n}\n",
        "http_status_code": 400
    },
    "error": {
        "http_status_code": 400,
        "error_message": "ApiDestination returned HTTP status 400 with payload: {\n  \"error\": {\n    \"code\": 400,\n    \"message\": \"Invalid JSON payload received. Unknown name \\\"cards_v234567890\\\" at 'message': Cannot find field.\",\n    \"status\": \"INVALID_ARGUMENT\",\n    \"details\": [\n      {\n        \"@type\": \"type.googleapis.com/google.rpc.BadRequest\",\n        \"fieldViolations\": [\n          {\n            \"field\": \"message\",\n            \"description\": \"Invalid JSON payload received. Unknown name \\\"cards_v234567890\\\" at 'message': Cannot find field.\"\n          }\n        ]\n      }\n    ]\n  }\n}\n"
    }
}
{
    "resource_arn": "arn:aws:events:us-east-1:<AWSアカウントID>:event-bus/default",
    "message_timestamp_ms": 1753281211849,
    "event_bus_name": "default",
    "request_id": "6cbc231c-c379-4168-88f4-9ddcf64612ab",
    "event_id": "5c93dd68-6982-1a51-142e-2ccc2d8e3d7e",
    "invocation_id": "5c93dd68-6982-1a51-142e-2ccc2d8e3d7e_3fe723ab-f67e-511f-439c-99fadcfb7be3",
    "message_type": "INVOCATION_FAILURE",
    "log_level": "ERROR",
    "details": {
        "rule_arn": "arn:aws:events:us-east-1:<AWSアカウントID>:rule/GoogleChatAwsNotification-NotificationConstructRule-eyR5rsqDuIp0",
        "role_arn": "arn:aws:iam::<AWSアカウントID>:role/GoogleChatAwsNotification-NotificationConstructRole-KE4kuzUAsJe3",
        "target_arn": "arn:aws:events:us-east-1:<AWSアカウントID>:api-destination/NotificationConstructDestinationApiDestinationEDEEF-qxr7gZIj4H7b/102baef6-979b-4615-a2ef-0412ec89b175",
        "target_input": "{\n  \"text\": \"👋🌎 こんにちは! AWSに関する通知だよ!!以下のメッセージを確認してね 🌎👋\",\n  \"cards_v234567890\": [\n    {\n      \"card\": {\n        \"header\": {\n          \"title\": \"CloudWatch Alarm State Change\",\n          \"image_url\": \"https://fonts.gstatic.com/s/i/short-term/release/googlesymbols/error/default/24px.svg\"\n        },\n        \"sections\": [\n          {\n            \"header\": \"<a href='https://us-east-1.console.aws.amazon.com/cloudwatch/home?region=us-east-1#alarmsV2:alarm/GoogleChatAwsNotificationStack-AlarmConstruct19D9277E-4sEB1Om9TpR4'>CloudWatchアラーム情報</a></a>\",\n            \"widgets\": [\n              {\n                \"text_paragraph\": {\n                  \"text\": \"AWSアカウントID : <AWSアカウントID>\"\n                }\n              },\n              {\n                \"text_paragraph\": {\n                  \"text\": \"リージョン : us-east-1\"\n                }\n              },\n              {\n                \"text_paragraph\": {\n                  \"text\": \"CloudWatchアラーム名 : GoogleChatAwsNotificationStack-AlarmConstruct19D9277E-4sEB1Om9TpR4\"\n                }\n              },\n              {\n                \"text_paragraph\": {\n                  \"text\": \"CloudWatchアラームの説明 : これは何かタグが付与されたことを知らせるアラートです。\"\n                }\n              }\n            ]\n          },\n          {\n            \"header\": \"現在の状態\",\n            \"widgets\": [\n              {\n                \"text_paragraph\": {\n                  \"text\": \"状態 : ALARM\"\n                }\n              },\n              {\n                \"text_paragraph\": {\n                  \"text\": \"理由 : Threshold Crossed: 1 datapoint [1.0 (23/07/25 14:32:00)] was greater than or equal to the threshold (1.0).\"\n                }\n              },\n              {\n                \"text_paragraph\": {\n                  \"text\": \"時刻 : 2025-07-23T14:33:31.519+0000\"\n                }\n              }\n            ]\n          },\n          {\n            \"header\": \"前回の状態\",\n            \"widgets\": [\n              {\n                \"text_paragraph\": {\n                  \"text\": \"状態 : OK\"\n                }\n              },\n              {\n                \"text_paragraph\": {\n                  \"text\": \"理由 : Threshold Crossed: no datapoints were received for 1 period and 1 missing datapoint was treated as [NonBreaching].\"\n                }\n              },\n              {\n                \"text_paragraph\": {\n                  \"text\": \"時刻 : 2025-07-23T14:29:31.529+0000\"\n                }\n              }\n            ]\n          }\n        ]\n      }\n    }\n  ]\n}",
        "target_properties": "{\"httpProperties\":{\"pathParameterValues\":[],\"headerParameters\":{},\"queryStringParameters\":{}}}",
        "total_attempts": 1,
        "final_invocation_status": "INVALID_PARAMETER",
        "ingestion_to_start_latency_ms": 75,
        "ingestion_to_complete_latency_ms": 294,
        "target_duration_ms": 218,
        "target_response_body": "{\n  \"error\": {\n    \"code\": 400,\n    \"message\": \"Invalid JSON payload received. Unknown name \\\"cards_v234567890\\\" at 'message': Cannot find field.\",\n    \"status\": \"INVALID_ARGUMENT\",\n    \"details\": [\n      {\n        \"@type\": \"type.googleapis.com/google.rpc.BadRequest\",\n        \"fieldViolations\": [\n          {\n            \"field\": \"message\",\n            \"description\": \"Invalid JSON payload received. Unknown name \\\"cards_v234567890\\\" at 'message': Cannot find field.\"\n          }\n        ]\n      }\n    ]\n  }\n}\n",
        "http_status_code": 400
    },
    "error": {
        "http_status_code": 400,
        "error_message": "ApiDestination returned HTTP status 400 with payload: {\n  \"error\": {\n    \"code\": 400,\n    \"message\": \"Invalid JSON payload received. Unknown name \\\"cards_v234567890\\\" at 'message': Cannot find field.\",\n    \"status\": \"INVALID_ARGUMENT\",\n    \"details\": [\n      {\n        \"@type\": \"type.googleapis.com/google.rpc.BadRequest\",\n        \"fieldViolations\": [\n          {\n            \"field\": \"message\",\n            \"description\": \"Invalid JSON payload received. Unknown name \\\"cards_v234567890\\\" at 'message': Cannot find field.\"\n          }\n        ]\n      }\n    ]\n  }\n}\n"
    }
}

errorに「cards_v234567890という不正なペイロードを受け取った」と具体的に記載がありますね。

Lambda関数編

実行時にエラーとなった場合

Lambda関数でも試します。

以下のようにエラーをスローするだけのLambda関数を用意しました。

export const handler = async (event) => {
  console.log(event);
  throw new Error("dosukoi");
};

EventBridge RuleにこちらのLambda関数を呼び出すようにターゲットを追加します。

4.現在のターゲット.png

この状態でEventBridge Ruleが動作するようにEC2インスタンスにタグ付けを行います。

しかし、Event Busで指定したCloudWatch Logsロググループには何も記録されていませんでした。

一方、Lambda関数自体は実行されています。

5.Lambda関数のログ.png

ということで、Lambda関数が何かしらの処理でエラーになった場合はEventBridgeのログ出力の仕組みでは検出できません。他の方法で気づく必要があります。

ちなみに、同様にStep Functionsのステートマシンをターゲットとして呼び出す場合も、ステートマシンの実行が失敗をしてもログ出力はされませんでした。

特にAPI Destinationのトラブルシューティングが捗りそう

Amazon EventBridgeのログ出力機能でAPI DestinationやLambda関数の実行時エラーをログ出力できるか確認してみました。

結論、API Destionattionについてはログ出力されていましたが、Lambda関数やStep Functionsステートマシンの実行時エラーはログ出力されませんした。

とはいえ、後者はターゲット側のログやCloudWatchメトリクスを見れば、すぐ自体には気づけるため、さして気になることではないように思えます。

API Destinationについては中々トラブルシューティングしづらい領域だったのでありがたいですね。少なくともログレベルをERRORに設定しても良いでしょう。

この記事が誰かの助けになれば幸いです。

以上、クラウド事業本部 コンサルティング部の のんピ(@non____97)でした!

この記事をシェアする

facebookのロゴhatenaのロゴtwitterのロゴ

© Classmethod, Inc. All rights reserved.