Enable API Gateway CloudWatch Logs

API Gateway Cloudwatch logs can help in troubleshooting issues related to request execution or client access to your API. This blog will help in understanding details to enable CloudWatch Logs for troubleshooting API Gateway REST API or WebSocket API

Execution Logs vs Access Logs

There are two types of API Gateway Cloudwatch logs: Execution logs and Access logs.

Execution Logs: Execution logs data that includes errors or request data (such as request or response parameter values or payloads), data used by authorizers , API keys, usage plans etc. When an API is deployed, API Gateway creates a log group and log streams under the log group. The log group is named following the API-Gateway-Execution-Logs_{rest-api-id}/{stage_name} format.

AccessLogs: Access logs are not detailed logs like execution logs but just contain the details of who accessed the API and how was the API accessed. You can create your own log group or choose an existing log group for access logs.

Note: Execution logs being detailed logs might contain some sensitive information therefore, In certain scenarios only access logs are preferred to be enabled. However, Execution logs can be enabled temporarily only for troubleshooting.

In certain scenarios, depending on at what stage the request failed you may see an entry only in access logs or both execution logs or no trace of request at all in logs.

  • No access logs and execution logs generated – Request failed at very early stage due to a
    • 400 Bad Request e.g. invalid resource or stage or endpoint or any other reason making a request bad
    • 429 Requests throttled
    • 413 Request Entity Too Large errors
    • 400 series errors from requests sent to a custom domain that has no API mapping
    • 500 series errors caused by internal failures
  • An entry in access logs but no execution logs – Request received by API Gateway but failed before API Gateway could invoke authorizers or execute request methods.
  • An Entry in both access logs and execution logs – Request received and processed by API Gateway. The error may occur during method/integration request/response phase.

Step 1: Create an IAM role for logging to CloudWatch

Note: API Gateway calls AWS Security Token Service in order to assume the IAM role, so make sure that AWS STS is enabled for the Region. Read : Activating and deactivating AWS STS in an AWS Region

1.    In the AWS Identity and Access Management (IAM) console, in the left navigation pane, choose Roles.

2.    On the Roles pane, choose Create role.

3.    On the Create role page, do the following:
For Select type of trusted entity, choose AWS Service.
For Choose a use case, choose API Gateway.
For Select your use case, choose API Gateway.
Choose Next: Permissions.

4.    Add AWS managed policy AmazonAPIGatewayPushToCloudWatchLogs which has all the required permissions.

5.    Continue with defaults till Next: Review.

6.    Under Review, do the following:
For Role name, enter a name for the role.
Choose Create role.

7.    On the Roles pane, in the search bar, enter the name of the role that you created. Then, choose the role from the search results.

8.    On the Summary pane, copy the Role ARN. You’ll need this ARN in the next section.

Step 2: Add the IAM role in the API Gateway console

Note: If you're developing multiple APIs across different AWS Regions, complete these steps in each Region.

1.    In the API Gateway console, choose your API.

2.    In the left navigation pane, at the bottom, below the Client Certificates section, choose Settings.

3.    Under Settings -> CloudWatch log role ARN, paste the IAM role ARN.

4.    Choose Save.

Step 3: Turn on Execution logs for your API and stage

  • Navigate to API Gateway Console -> API -> Stages -> Stage
  • On the Stage Editor pane, choose the Logs/Tracing tab.
  • On the Logs/Tracing tab, under CloudWatch Settings, do the following to turn on execution logging:
    • Choose the Enable CloudWatch Logs check box.
    • For Log level, choose INFO to generate execution logs for all requests. Or, choose ERROR to generate execution logs only for requests to your API that result in an error.
    • For REST APIs, choose the Log full requests/responses data check box. Or, for WebSocket APIs, choose the Log full message data check box.
Note: Enabling full requests/responses or full message data will capture all headers/query string parameters/body in the logs which may log any sensitive information (if present) in logs as well.

Step 4: Turn on Access logs for your API and stage

  • Navigate to API Gateway Console -> API -> Stages -> Stage
  • On the Stage Editor pane, choose the Logs/Tracing tab.
  • Under Custom Access Logging, do the following to turn on access logging:
    – Choose the Enable Access Logging check box.
    – For Access Log Destination ARN, enter the ARN of a CloudWatch log group or an Amazon Kinesis Data Firehose stream.
Note : ARN should be of format arn:aws:logs:Region:AccountID:log-group:LogGroupName . If you copy ARN from CloudWatch Console do not add :* from the ARN 
  • Enter a Log Format. one of your choice from the CLF, JSON, XML, or CSV to see an example in that format.

As a minimum add following variables to the access log format

$context.extendedRequestId $context.identity.sourceIp $context.identity.caller $context.identity.user [$context.requestTime] "$context.httpMethod $context.resourcePath $context.protocol" $context.status $context.responseLength $context.requestId

For a detailed list of all context variables available for access logging see here

4. Choose Save Changes.

Step 5: Test Logging

Send a request to your API from API Gateway Test console or call API using deployed Invoke URL from external client like Postman/cURL/Browser etc and check for the logs generated in cloudwatch.

Find Logs for a Particular Request

When you access an API Gateway API, In almost every(unless something wrong happened with the request), In response headers you will see x-amzn-requestid and x-amz-apigw-id header. Following is a cURL output

< date: Sun, 12 May 2021 05:56:09 GMT
< content-type: application/json
< content-length: 26
< x-amzn-requestid: c89905qr-****-****-b23c-a373c095a0d1
< x-amz-apigw-id: faBO-HW_*****_w=

Value of x-amzn-requestid can be used to trace a particular request. An easy way is to use CloudWatch Log Insights.

  • Open the CloudWatch console at https://console.aws.amazon.com/cloudwatch/
  • In the navigation pane, choose Insights.
  • Enter name of API Gateway Execution Log Group or Access Log Group in the drop down provided above the query editor.
  • Use the time selector at the upper right to select the time period in which the API request was made.
  • Enter following query
fields @timestamp, @message
| filter @message like /c89905qr-****-****-b23c-a373c095a0d1/
| sort @timestamp desc
  • Choose Run

Happy Troubleshooting !!

References:

  1. https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-logging.html
  2. https://aws.amazon.com/premiumsupport/knowledge-center/api-gateway-cloudwatch-logs/
  3. https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html