Amazon EventBridgeのログ出力機能でAPI DestinationやLambda関数の実行時エラーをログ出力できるか確認してみた
AWSのAPIコール以外でもエラー時のログを出力してくれるのか気になる
こんにちは、のんピ(@non____97)です。
皆さんはAmazon EventBridgeのログ出力機能がAWSのAPIコール以外でもエラー時のログを出力してくれるのか気になったことはありますか? 私はあります。
先日Amazon EventBridgeのEvent Busでログ出力設定ができるようになったアップデートを紹介しました。
これにより、以下のようなログを記録できるようになりました。
- Event Busでイベントの受信が成功/失敗した
- イベントがEventBridge Ruleのイベントパターンにマッチした/していない
- ターゲットの呼び出しが成功/失敗した
上述の記事では実際にターゲットとして指定したCloudWatch Logsロググループに正常に書き込みが行えたかどうか確認した訳ですが、AWSのAPIコール以外でも同様にログ出力されるかどうか気になりました。
最近ではEvntBridge API DestionationとInput Transformeterを用いて、あるイベントをトリガーに外部のAPIにアクセスすることも多いでしょう。
従来、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
EventBridge Rule的にはターゲットを呼び出すまでが責務なのであれば、正常に呼び出したLambda関数内で発生したエラーについては感知しないように思えます。
実際に確認してみました。
いきなりまとめ
- EventBridge API Destinationの実行時エラーをログ出力することが可能
- Lambda関数やStep Functinnsステートマシンでは実行時エラーをログ出力することはできない
- エラー時にログを出力するかは各ターゲットごとに事前検証した方が良さそう
EventBridge API Destination編
Webhook URLが正しくない場合
まず、EventBridge API Destionation編です。
以下環境で用意したリソースをそのまま再利用します。
API Destionationで定義しているWebhook URLのtoken
末尾にDosukoiWasshoi
を付与します。
defaultのEvent BusのログレベルをERRORにして、CloudWatch Logsに出力するように設定します。
この状態で適当に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のテンプレートはもともと以下のとおりです。
{
"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関数を呼び出すようにターゲットを追加します。
この状態でEventBridge Ruleが動作するようにEC2インスタンスにタグ付けを行います。
しかし、Event Busで指定したCloudWatch Logsロググループには何も記録されていませんでした。
一方、Lambda関数自体は実行されています。
ということで、Lambda関数が何かしらの処理でエラーになった場合はEventBridgeのログ出力の仕組みでは検出できません。他の方法で気づく必要があります。
ちなみに、同様にStep Functionsのステートマシンをターゲットとして呼び出す場合も、ステートマシンの実行が失敗をしてもログ出力はされませんでした。
特にAPI Destinationのトラブルシューティングが捗りそう
Amazon EventBridgeのログ出力機能でAPI DestinationやLambda関数の実行時エラーをログ出力できるか確認してみました。
結論、API Destionattionについてはログ出力されていましたが、Lambda関数やStep Functionsステートマシンの実行時エラーはログ出力されませんした。
とはいえ、後者はターゲット側のログやCloudWatchメトリクスを見れば、すぐ自体には気づけるため、さして気になることではないように思えます。
API Destinationについては中々トラブルシューティングしづらい領域だったのでありがたいですね。少なくともログレベルをERRORに設定しても良いでしょう。
この記事が誰かの助けになれば幸いです。
以上、クラウド事業本部 コンサルティング部の のんピ(@non____97)でした!