Amazon API Gatewayのログには、API Gatewayがリクエストを処理した過程を残す「実行ログ」と、誰がどのAPIを呼んだかを1行ずつ残す「アクセスログ」の2種類があります。どちらもCloudWatch Logsへ出せますが、HTTP APIでは実行ログが使えず、REST APIではRegionごとにIAMロールを登録しないと何も出力されません。本記事では、API種類ごとに使えるログ、IAMロールの登録、ログレベルとデータトレースの設定、調査に使えるJSON形式のアクセスログ、X-Rayを組み合わせた障害調査の手順を、そのまま実行できるCLIとともにまとめました。APIゲートウェイという仕組みそのものはAPIゲートウェイとは?役割・機能とリバースプロキシ/サービスメッシュとの違い・導入判断を解説で扱っています。仕様は2026年10月時点の公式ドキュメントで確認した内容です。
まとめ:アクセスログは全ステージで出し、実行ログはERRORで常時オンにする
本番のREST APIでは、アクセスログをJSON形式で全ステージに出し、実行ログはログレベルERRORで常に有効にしておく構成を基本にします。障害が起きたときだけINFOへ上げれば、再デプロイなしで処理の詳細が残り始めます。リクエストとレスポンスの全文を記録するデータトレースは、本番では使いません。
最初につまずくのは権限です。REST APIとWebSocket APIは、API Gatewayのアカウント設定にcloudwatchRoleArnを登録しないとログを書き込めません。HTTP APIはアクセスログしか持たず、設定の手順も別のCLIです。アクセスログにはrequestIdとextendedRequestIdを必ず入れてください。この2つがあれば、実行ログやX-Rayのトレースへ同じリクエストをたどれます。
API Gatewayのログ2種類|実行ログとアクセスログの違いとAPI種類別の対応
2種類のログは記録する中身も、ロググループの持ち主も違います。どちらか片方だけを有効にすることもできます。
実行ログとアクセスログが記録する内容と1KB切り詰め・ロググループ名の違い
REST APIの実行ログの解説によると、実行ログにはエラー、処理のトレース、リクエストとレスポンスのパラメータや本文、Lambdaオーソライザーが使ったデータ、APIキーや使用量プランの要否が記録されます。ロググループはAPI Gatewayが自動で作り、名前はAPI-Gateway-Execution-Logs_{rest-api-id}/{stage_name}で固定です。1件のログは1KBで切り詰められます。
アクセスログの解説では、アクセスログは自分で用意したロググループへ、自分で選んだ$context変数を、CLF・JSON・XML・CSVのいずれかの形式で出す仕組みです。1リクエストにつき1行なので、件数の集計やエラー率の算出に向きます。実行ログは1リクエストで複数行になるため、個別の調査に使います。
REST・HTTP・WebSocket別に使えるログ出力先とX-Rayの対応表
使えるログはAPIの種類で決まります。REST APIとHTTP APIの機能比較とWebSocket APIのログ設定の記載を並べると次のとおりです。
| API種類 | 実行ログ | アクセスログ | Firehose | X-Ray |
|---|---|---|---|---|
| REST API | あり | あり | あり | あり |
| HTTP API | なし | あり | なし | なし |
| WebSocket API | あり | あり | 記載なし | 記載なし |
HTTP APIは料金が安い代わりに、調査の手段がアクセスログとメトリクスに限られます。オーソライザーのどこで止まったか、バックエンドに何を送ったかを後から確かめたい要件があるなら、REST APIを選ぶ根拠として十分です。WebSocket APIのアクセスログでは、$context.eventType(CONNECT・MESSAGE・DISCONNECT)と$context.connectionIdを入れると接続単位で追えます。
ログ出力のIAMロール設定|Region別のcloudwatchRoleArn登録
REST APIとWebSocket APIでは、ステージの設定より先にアカウント側の設定が要ります。ここが抜けていると、ステージでログを有効にしようとした時点でエラーになります。
ログ書き込み用の管理ポリシーを付けたIAMロールのCLI作成手順
CloudWatchログ記録の権限の解説では、apigateway.amazonaws.comを信頼するIAMロールに管理ポリシーAmazonAPIGatewayPushToCloudWatchLogsを付け、そのARNをアカウントのcloudwatchRoleArnに設定するよう求めています。ポリシーの中身はロググループとログストリームの作成、logs:PutLogEventsなど7つのアクションです。AmazonAPIGatewayPushToCloudWatchLogsを付けたIAMロールをCLIで作り、東京リージョンで登録する例を示します。
# 1) API Gatewayが引き受けるロールを作る
aws iam create-role --role-name APIGatewayPushToCloudWatchLogs \
--assume-role-policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"Service":"apigateway.amazonaws.com"},"Action":"sts:AssumeRole"}]}'
# 2) 管理ポリシーを付ける
aws iam attach-role-policy --role-name APIGatewayPushToCloudWatchLogs \
--policy-arn arn:aws:iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs
# 3) Regionごとにアカウント設定へ登録し、反映を確かめる
aws apigateway update-account --region ap-northeast-1 \
--patch-operations op=replace,path=/cloudwatchRoleArn,value=arn:aws:iam::123456789012:role/APIGatewayPushToCloudWatchLogs
aws apigateway get-account --region ap-northeast-1 --query cloudwatchRoleArn
update-accountのリファレンスどおり、パッチのパスは/cloudwatchRoleArnで、Wが小文字です。登録はRegion単位なので、大阪リージョンにもAPIを置くならap-northeast-3で手順3を繰り返します。
ロールARN未設定エラーの対処とHTTP APIで必要なIAM権限の違い
ステージでログを有効にしたときに「CloudWatch Logs role ARN must be set in account settings to enable logging」と表示されたら、そのRegionで手順3が済んでいません。ロールを登録してもエラーが続く場合は、そのRegionでAWS STSが無効になっていないかを確かめます。API GatewayはSTSを呼んでロールを引き受けるためです。
HTTP APIの手順は仕組みが違います。HTTP APIのログ設定にはcloudwatchRoleArnの登録が含まれず、代わりに設定する利用者のIAMにlogs:CreateLogDeliveryやlogs:PutResourcePolicyなどの権限を求めています。HTTP APIでログが出ないときは、アカウント設定ではなく操作者の権限を見直してください。
実行ログの有効化手順|ログレベルERROR・INFOとデータトレースの使い分け
実行ログはステージのメソッド設定として持ちます。ステージ全体に一括で掛けることも、特定のメソッドだけ変えることもできます。
update-stageのパッチ操作でステージ全体のログレベルを切り替えるコマンド
UpdateStageのパッチ操作一覧では、ログレベルは/{resourcePath}/{httpMethod}/logging/loglevel、データトレースは同じ階層のlogging/dataTraceで変更します。ステージ全体に掛けるときは、リソースとメソッドの両方を*にします。
# ステージ全体をERRORにし、データトレースを切る
aws apigateway update-stage --rest-api-id a1b2c3d4e5 --stage-name prod \
--patch-operations \
'op=replace,path=/*/*/logging/loglevel,value=ERROR' \
'op=replace,path=/*/*/logging/dataTrace,value=false'
# 障害調査の間だけINFOへ上げる(終わったらERRORに戻す)
aws apigateway update-stage --rest-api-id a1b2c3d4e5 --stage-name prod \
--patch-operations 'op=replace,path=/*/*/logging/loglevel,value=INFO'
ERRORはエラーになったリクエストだけ、INFOはすべてのリクエストを記録します。ステージ設定の変更に再デプロイは要らないので、調査の開始と終了はコマンド1本で切り替え可能です。CloudFormationではAWS::ApiGateway::StageのMethodSettingsにLoggingLevelを書きます。
データトレースを本番で使わない理由とメソッド単位で一時的に有効にする方法
データトレースはリクエストとレスポンスの全文を実行ログに残す機能で、公式ドキュメントは本番のAPIでの使用を勧めていません。マスクの対象として挙がっているのは認可ヘッダーやAPIキーの値などのパラメータで、本文に入った氏名や住所は対象に挙がっていません。個人情報を扱うAPIで有効にすると、ログの閲覧権限がそのまま個人情報の閲覧権限になります。
どうしても本文を見たいときは、問題のメソッドだけに限って短時間だけ有効にします。パスの/は~1に置き換えるので、/ordersのPOSTなら次のように指定します。
aws apigateway update-stage --rest-api-id a1b2c3d4e5 --stage-name stg \
--patch-operations 'op=replace,path=/~1orders/POST/logging/dataTrace,value=true'
本番ではなく検証ステージで同じリクエストを再現して見るのが先です。調べ終えたらvalue=falseで必ず戻してください。
実行ログの保持期間とCloudWatch Logs deliveryの1MB上限
自動で作られる実行ログのロググループは、保持期間を設定しない限りログが消えません。作成後にput-retention-policyで日数を決めます。指定できる値は1、3、5、7、14、30、60、90日などの決まった選択肢です。
1KBの切り詰めで中身が読めない場合は、CloudWatch Logs deliveryで実行ログを送る手順に切り替えます。1件1MBまで残せ、宛先に自分のロググループ、S3、Firehoseを選べて、複数の宛先へ同時にも送れます。
# 保持期間を30日にする
aws logs put-retention-policy \
--log-group-name "API-Gateway-Execution-Logs_a1b2c3d4e5/prod" --retention-in-days 30
# 実行ログを自分のロググループへ送る(ログレベルはERRORかINFOが前提)
aws logs put-delivery-source --name orders-prod-exec --log-type EXECUTION_LOGS \
--resource-arn arn:aws:apigateway:ap-northeast-1:123456789012:/restapis/a1b2c3d4e5/stages/prod
aws logs put-delivery-destination --name orders-prod-exec-dest \
--delivery-destination-configuration "destinationResourceArn=arn:aws:logs:ap-northeast-1:123456789012:log-group:apigw-exec-orders-prod"
aws logs create-delivery --delivery-source-name orders-prod-exec \
--delivery-destination-arn arn:aws:logs:ap-northeast-1:123456789012:delivery-destination:orders-prod-exec-dest
deliveryを作ると、API Gatewayは自動作成のロググループへの書き込みを止めます。旧ロググループを見ているアラームやダッシュボード、サブスクリプションフィルターは先に付け替えてください。配信はベストエフォートで、まれに届かないイベントがあると明記されています。
アクセスログの設定手順|JSON形式の推奨フィールドとHTTP APIでの設定
アクセスログは形式を自分で決めるため、後で集計しやすい形を最初に作っておくと調査の手間が大きく変わります。
障害調査用のリクエストIDを含むアクセスログのJSONフォーマット例
アクセスログの形式には$context.requestIdか$context.extendedRequestIdのどちらかが必須で、公式は両方を入れるよう勧めています。前者はクライアントが上書きできる値、後者はAPI Gatewayが発行し上書きできない値で、AWSサポートへの問い合わせにも使います。アクセスログの変数一覧から、障害調査に使う変数を足したJSON形式の例です。requestIdとextendedRequestIdを含むこのJSONフォーマットは、アクセスログの設定時に1行で書きます。
{"requestId":"$context.requestId","extendedRequestId":"$context.extendedRequestId","requestTime":"$context.requestTime","ip":"$context.identity.sourceIp","httpMethod":"$context.httpMethod","path":"$context.resourcePath","status":"$context.status","responseType":"$context.error.responseType","errorMessage":$context.error.messageString,"authorizerError":"$context.authorizer.error","wafStatus":"$context.waf.status","integrationStatus":"$context.integration.status","integrationLatency":"$context.integrationLatency","responseLatency":"$context.responseLatency","xrayTraceId":"$context.xrayTraceId"}
errorMessageだけ引用符で囲んでいないのは、$context.error.messageStringが引用符付きの値を返すためです。$context.error.messageを引用符で囲む書き方だと、メッセージ中の記号でJSONが壊れる場合があります。WAFを関連付けたステージではwafStatusが403の出どころを示す値です。WAF側の設定はAPI GatewayにAWS WAFを関連付ける手順で解説しています。
REST APIとHTTP APIのアクセスログ設定に使うCLIの違いと実行例
REST APIでは、宛先のロググループARNをaccessLogSettings/destinationArnに、形式をaccessLogSettings/formatに設定します。形式の文字列にはカンマが入るため、パッチはJSONファイルで渡します。ここでは前のh3の形式から一部の項目に絞りました。
# patch.json
[
{"op":"replace","path":"/accessLogSettings/destinationArn","value":"arn:aws:logs:ap-northeast-1:123456789012:log-group:apigw-access-orders-prod"},
{"op":"replace","path":"/accessLogSettings/format","value":"{\"requestId\":\"$context.requestId\",\"extendedRequestId\":\"$context.extendedRequestId\",\"path\":\"$context.resourcePath\",\"status\":\"$context.status\",\"responseType\":\"$context.error.responseType\",\"integrationLatency\":\"$context.integrationLatency\"}"}
]
aws logs create-log-group --log-group-name apigw-access-orders-prod
aws apigateway update-stage --rest-api-id a1b2c3d4e5 --stage-name prod \
--patch-operations file://patch.json
# HTTP APIは別のCLI(apigatewayv2)で設定する
aws apigatewayv2 update-stage --api-id abcdef1234 --stage-name '$default' \
--access-log-settings '{"DestinationArn":"arn:aws:logs:ap-northeast-1:123456789012:log-group:apigw-http-access","Format":"{\"requestId\":\"$context.requestId\",\"routeKey\":\"$context.routeKey\",\"status\":\"$context.status\",\"extendedRequestId\":\"$context.extendedRequestId\"}"}'
HTTP APIでは$context.resourcePathの代わりに$context.routeKeyを使います。どちらのAPIでも、アクセスログの設定変更に再デプロイは要りません。
Firehoseへのアクセスログ配信に必要な接頭辞と宛先の排他条件
アクセスログをS3やログ分析基盤へ直接流したいときは、宛先をAmazon Data Firehoseにできます。Firehoseへのログ記録の解説には、ストリーム名をamazon-apigateway-で始めるという命名の決まりがあります。名前が違うストリームは宛先に指定できません。
アクセスログの宛先はCloudWatch LogsかFirehoseのどちらか一方です。両方へは同時に出せません。実行ログをCloudWatch Logsに、アクセスログをFirehoseに分ける構成は可能です。Firehoseを使うと、API GatewayはサービスリンクロールAWSServiceRoleForAPIGatewayを自動で作ります。
ログとX-Rayを使った障害調査|4xx・5xxの原因をリクエストIDでたどる
調査は「アクセスログで傾向をつかむ」「実行ログで1件を掘る」「X-Rayで遅い区間を特定する」の順に進めます。
401・403・429・5xxを応答種別とパスで集計するクエリ
前述のJSON形式でアクセスログを出していれば、CloudWatch Logs Insightsで項目名をそのまま使えます。アクセスログのロググループを選び、次のクエリを実行します。
fields @timestamp, status, responseType, path, authorizerError, wafStatus
| filter status like /^[45]/
| stats count() as cnt by status, responseType, path, bin(5m)
| sort cnt desc
| limit 50
401や403でauthorizerErrorに値があればオーソライザーでの拒否、wafStatusが403ならWAFでの遮断、429はスロットリングです。504でresponseTypeがINTEGRATION_TIMEOUTなら時間切れなので、API Gatewayのタイムアウトの上限と504の切り分けの手順に進みます。Logs Insightsはスキャンしたデータ量で課金されるため、時間範囲を絞ってから実行します。課金の仕組みはCloudWatch Logs Insightsの料金と使い方にまとめました。
アクセスログのrequestIdから実行ログの処理過程を引き当てる手順
傾向がつかめたら、エラーになった1件のrequestIdを控えます。実行ログの各行にはリクエストIDが入っているため、実行ログのロググループで次のクエリを流すと、そのリクエストの処理過程が時系列で並びます。
fields @timestamp, @message
| filter @message like "c0ffee12-3456-4789-abcd-ef1234567890"
| sort @timestamp asc
オーソライザーの判定結果、バックエンドへ送ったリクエスト、受け取ったステータスの順に追えば、どの段階で失敗したかが分かります。ログレベルがERRORだと成功した処理の行は残らないため、正常系との比較が要るときだけINFOへ上げます。Lambda側の実行ログの読み方はAWS Lambdaのログ運用ガイドを参照してください。
X-Rayのアクティブトレースを有効にしてxrayTraceIdをログに残す設定
遅延の原因が、API Gateway、Lambda、その先のデータベースのどこにあるかを分けるにはX-Rayを使います。X-Rayの設定手順では、ステージでアクティブトレースを有効にすると、既定の記録対象は毎秒1件と、それを超えた分の5%のリクエストです。初回の有効化時にはサービスリンクロールAWSServiceRoleForAPIGatewayが作られます。
aws apigateway update-stage --rest-api-id a1b2c3d4e5 --stage-name prod \
--patch-operations op=replace,path=/tracingEnabled,value=true
アクセスログに$context.xrayTraceIdを入れておけば、エラーになった1件のトレースをX-Rayのコンソールで直接開けます。全件が記録されるわけではないため、トレースIDが空の行が混ざるのは正常な状態です。X-Rayのサービスマップやサンプリングルールの詳細はAWS X-Rayとはで解説しています。
ログ設定の採用判断|環境別の推奨値と過剰になる設定・見送る場面
ログは多く残すほど調査は楽になりますが、費用と情報漏えいの面積も増えます。環境ごとに線を引きます。
本番・検証・開発で分けるログレベル・データトレース・X-Rayの推奨値
| 設定項目 | 本番 | 検証 | 開発 |
|---|---|---|---|
| 実行ログ | ERROR | INFO | INFO |
| データトレース | 使わない | 調査時のみ | 可 |
| アクセスログ | JSON・必須 | JSON・必須 | 任意 |
| X-Ray | 既定サンプリング | 有効 | 任意 |
| 保持期間 | 監査要件に合わせる | 30日 | 7日 |
本番のERROR常時オンは、Security HubのAPI Gateway向けコントロールのAPIGateway.1(実行ログがERRORかINFO)も満たします。HTTP APIのステージはAPIGateway.9でアクセスログの設定を確認されるので、HTTP APIでもアクセスログは省きません。
INFO常時オンと全項目アクセスログを見送るべき高トラフィックAPIの条件
月に数千万件を超えるリクエストを受けるAPIで、実行ログをINFOのまま常時オンにする設定は見送ります。1リクエストで複数行が出るため、CloudWatch Logsの取り込み料金がAPI Gatewayのリクエスト料金の数割に達します。料金記事の試算では、1件2KBのログでREST APIのリクエスト料金の約3分の1でした。ログを含めた費用の試算はAPI Gatewayの料金を東京リージョンの実額で計算するで扱っています。
アクセスログに$context.identity.userAgentや認証クレームなどを手当たり次第に足す設計も過剰です。使わない項目は1行の容量を増やし、個人に結び付く情報を長期保存するリスクだけが残ります。調査で実際に使う項目に絞り、保持期間も決めてから有効にしてください。ログ設計を含めたAPI基盤の構築や、既存APIの監視の見直しを外部に相談したい場合は、API開発・システム連携のページで支援内容を紹介しています。
API Gatewayのログ設定と障害調査についてよくある質問と回答
API Gatewayのログ設定で、設定時や障害対応の際によく出る質問に答えます。
API Gatewayのログはどこに出力されますか?
実行ログは、API Gatewayが自動で作るCloudWatch LogsのロググループAPI-Gateway-Execution-Logs_{rest-api-id}/{stage_name}に出ます。CloudWatch Logs deliveryを設定した場合は、送り先が自動作成のロググループから、自分で用意したロググループ、S3、Firehoseへ切り替わる仕組みです。アクセスログは、ステージに指定したCloudWatch LogsのロググループかFirehoseのストリームに出ます。
ログを有効にしたのにCloudWatchに何も出ないのはなぜですか?
REST APIとWebSocket APIでは、そのRegionのアカウント設定にcloudwatchRoleArnが登録されていないとログが書き込まれません。登録済みなら、ログレベルがOFFのままになっていないか、アクセスログの宛先ARNが別のRegionやアカウントのロググループを指していないかを確かめてください。HTTP APIでは操作者のIAM権限を確認します。
HTTP APIで実行ログを出す方法はありますか?
ありません。2026年10月時点の公式の機能比較では、実行ログ、Firehoseへのアクセスログ、X-RayはいずれもREST API専用です。HTTP APIで調べられるのはアクセスログとCloudWatchメトリクスです。オーソライザーやバックエンドとのやり取りを詳しく残す必要があるなら、REST APIを選んでください。
ログの設定を変えたらAPIの再デプロイは必要ですか?
不要です。公式ドキュメントには、ステージの設定、ログ、ステージ変数を変えても再デプロイは要らないと書かれています。障害調査の間だけ実行ログをINFOへ上げ、終わったらERRORへ戻す運用は、この性質を前提にしています。統合のタイムアウトのようにAPIの定義そのものを変えた場合は、再デプロイが必要です。
API Gatewayのログにリクエスト本文は残りますか?
実行ログでデータトレースを有効にしたときだけ、リクエストとレスポンスの本文が残ります。標準の実行ログは1件1KBで切り詰められるため、大きな本文は途中で切れます。アクセスログには本文を出す変数がありません。データトレースは本番での使用が推奨されていないので、検証ステージで再現して確かめてください。
関連記事
- APIゲートウェイとは?役割・機能とリバースプロキシ/サービスメッシュとの違い・導入判断を解説:ログ設定の前提になるAPIゲートウェイの役割と導入判断。
- API Gatewayのタイムアウト:29秒の上限を引き上げる手順と504の切り分け・非同期化:アクセスログで見つけた504を原因別に切り分ける手順。
- API Gatewayの料金を東京リージョンの実額で計算する:REST・HTTP・WebSocketの単価と付帯課金:実行ログやX-Rayを含めたAPI Gatewayの費用。
- API GatewayにAWS WAFを関連付ける手順:Web ACLのルール設計・WCU計算とCognito保護:アクセスログのwafStatusで見える403の出どころ。
- AWS X-Rayとは|CloudWatchとの違いとOpenTelemetry移行後の使い方【2026年版】:API GatewayのトレースをたどるX-Rayの仕組み。