

# Configure logging for HTTP APIs in API Gateway
<a name="http-api-logging"></a>

You can turn on logging to write logs to CloudWatch Logs. You can use [logging variables](http-api-logging-variables.md) to customize the content of your logs.

To improve your security posture, we recommend that you write logs to CloudWatch Logs for all stages of your HTTP API. You might need to do this to comply with various compliance frameworks. For more information, see [Amazon API Gateway controls](https://docs.amazonaws.cn/securityhub/latest/userguide/apigateway-controls.html) in the *Amazon Security Hub User Guide*.

To turn on logging for an HTTP API, you must do the following.

1. Ensure that your user has the required permissions to activate logging.

1. Create a CloudWatch Logs log group.

1. Provide the ARN of the CloudWatch Logs log group for a stage of your API.

## Permissions to activate logging
<a name="http-api-logging.permissions"></a>

To turn on logging for an API, your user must have the following permissions.

**Example**    
****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "logs:DescribeLogGroups",
                "logs:DescribeLogStreams",
                "logs:GetLogEvents",
                "logs:FilterLogEvents"
            ],
            "Resource": "arn:aws-cn:logs:us-west-2:123456789012:log-group:*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogDelivery",
                "logs:PutResourcePolicy",
                "logs:UpdateLogDelivery",
                "logs:DeleteLogDelivery",
                "logs:CreateLogGroup",
                "logs:DescribeResourcePolicies",
                "logs:GetLogDelivery",
                "logs:ListLogDeliveries"
            ],
            "Resource": "*"
        }
    ]
}
```

## Create a log group and activate logging for HTTP APIs
<a name="http-api-enable-logging"></a>

You can create a log group and activate access logging using the Amazon Web Services Management Console or the Amazon CLI.

------
#### [ Amazon Web Services Management Console ]

1.  Create a log group. 

   To learn how to create a log group using the console, see [Create a Log Group in Amazon CloudWatch Logs User Guide](https://docs.amazonaws.cn/AmazonCloudWatch/latest/logs/Working-with-log-groups-and-streams.html).

1. Sign in to the API Gateway console at [https://console.amazonaws.cn/apigateway](https://console.amazonaws.cn/apigateway).

1. Choose an HTTP API.

1. Under the **Monitor** tab in the primary navigation panel, choose **Logging**.

1. Select a stage to activate logging and choose **Select**. 

1. Choose **Edit** to activate access logging. 

1. Turn on **Access logging**, enter a CloudWatch Logs, and select a log format.

1. Choose **Save**.

------
#### [ Amazon CLI ]

The following [create-log-group](https://docs.amazonaws.cn/cli/latest/reference/logs/create-log-group.html) command creates a log group:

```
aws logs create-log-group --log-group-name my-log-group
```

You need the Amazon Resource Name (ARN) for your log group to turn on logging. The ARN format is arn:aws:logs:*region*:*account-id*:log-group:*log-group-name*.

The following [update-stage](https://docs.amazonaws.cn/cli/latest/reference/apigatewayv2/update-stage.html) command turns on logging for the `$default` stage of an HTTP API:

```
aws apigatewayv2 update-stage --api-id abcdef \
    --stage-name '$default' \
    --access-log-settings '{"DestinationArn": "arn:aws:logs:region:account-id:log-group:log-group-name", "Format": "$context.identity.sourceIp - - [$context.requestTime] \"$context.httpMethod $context.routeKey $context.protocol\" $context.status $context.responseLength $context.requestId"}'
```

------

## Example log formats
<a name="http-api-enable-logging.examples"></a>

Examples of some common access log formats are available in the API Gateway console and are listed as follows.
+ `CLF` ([Common Log Format](https://httpd.apache.org/docs/current/logs.html#common)):

  ```
  $context.identity.sourceIp - - [$context.requestTime] "$context.httpMethod $context.routeKey $context.protocol" $context.status $context.responseLength $context.requestId $context.extendedRequestId
  ```
+  `JSON`: 

  ```
  { "requestId":"$context.requestId", "ip": "$context.identity.sourceIp", "requestTime":"$context.requestTime", "httpMethod":"$context.httpMethod","routeKey":"$context.routeKey", "status":"$context.status","protocol":"$context.protocol", "responseLength":"$context.responseLength", "extendedRequestId": "$context.extendedRequestId" }
  ```
+ `XML`: 

  ```
  <request id="$context.requestId"> <ip>$context.identity.sourceIp</ip> <requestTime>$context.requestTime</requestTime> <httpMethod>$context.httpMethod</httpMethod> <routeKey>$context.routeKey</routeKey> <status>$context.status</status> <protocol>$context.protocol</protocol> <responseLength>$context.responseLength</responseLength> <extendedRequestId>$context.extendedRequestId</extendedRequestId> </request>
  ```
+ `CSV` (comma-separated values):

  ```
  $context.identity.sourceIp,$context.requestTime,$context.httpMethod,$context.routeKey,$context.protocol,$context.status,$context.responseLength,$context.requestId,$context.extendedRequestId
  ```

# Customize HTTP API access logs
<a name="http-api-logging-variables"></a>

You can use the following variables to customize HTTP API access logs. To learn more about access logs for HTTP APIs, see [Configure logging for HTTP APIs in API Gateway](http-api-logging.md).


| Parameter | Description | 
| --- | --- | 
| \$1context.accountId |  The API owner's Amazon account ID.  | 
| \$1context.apiId |  The identifier API Gateway assigns to your API.  | 
| \$1context.authorizer.claims.property |  A property of the claims returned from the JSON Web Token (JWT) after the method caller is successfully authenticated, such as `$context.authorizer.claims.username`. For more information, see [Control access to HTTP APIs with JWT authorizers in API Gateway](http-api-jwt-authorizer.md).  Calling `$context.authorizer.claims` returns null.   | 
| \$1context.authorizer.error | The error message returned from an authorizer. | 
| \$1context.authorizer.property |  The value of the specified key-value pair of the `context` map returned from an API Gateway Lambda authorizer function. For example, if the authorizer returns the following `context` map:  <pre>"context" : {<br />  "key": "value",<br />  "numKey": 1,<br />  "boolKey": true<br />}</pre> calling `$context.authorizer.key` returns the `"value"` string, calling `$context.authorizer.numKey` returns the `1`, and calling `$context.authorizer.boolKey` returns `true`.  | 
| \$1context.awsEndpointRequestId |  The Amazon endpoint's request ID from the `x-amz-request-id` or `x-amzn-requestId` header.  | 
| \$1context.awsEndpointRequestId2 |  The Amazon endpoint's request ID from the `x-amz-id-2` header.  | 
| \$1context.customDomain.basePathMatched |  The path for an API mapping that an incoming request matched. Applicable when a client uses a custom domain name to access an API. For example if a client sends a request to `https://api.example.com/v1/orders/1234`, and the request matches the API mapping with the path `v1/orders`, the value is `v1/orders`. To learn more, see [Map API stages to a custom domain name for HTTP APIs](http-api-mappings.md).  | 
| \$1context.dataProcessed | The amount of data processed in bytes. | 
| \$1context.domainName |  The full domain name used to invoke the API. This should be the same as the incoming `Host` header.  | 
| \$1context.domainPrefix |  The first label of the `$context.domainName`.  | 
| \$1context.error.message |  A string that contains an API Gateway error message.  | 
| \$1context.error.messageString | The quoted value of \$1context.error.message, namely "\$1context.error.message". | 
| \$1context.error.responseType |  A type of `GatewayResponse`. For more information, see [Monitor WebSocket API execution with CloudWatch metrics](apigateway-websocket-api-logging.md) and [Setting up gateway responses to customize error responses](api-gateway-gatewayResponse-definition.md#customize-gateway-responses).  | 
| \$1context.extendedRequestId | Equivalent to \$1context.requestId. | 
| \$1context.httpMethod |  The HTTP method used. Valid values include: `DELETE`, `GET`, `HEAD`, `OPTIONS`, `PATCH`, `POST`, and `PUT`.  | 
| \$1context.identity.accountId |  The Amazon account ID associated with the request. Supported for routes that use IAM authorization.  | 
| \$1context.identity.caller |  The principal identifier of the caller that signed the request. Supported for routes that use IAM authorization.  | 
| \$1context.identity.cognitoAuthenticationProvider |  A comma-separated list of all the Amazon Cognito authentication providers used by the caller making the request. Available only if the request was signed with Amazon Cognito credentials.  For example, for an identity from an Amazon Cognito user pool, `cognito-idp. region.amazonaws.com/user_pool_id,cognito-idp.region.amazonaws.com/user_pool_id:CognitoSignIn:token subject claim` For information about the available Amazon Cognito authentication providers, see [Using Federated Identities](https://docs.amazonaws.cn/cognito/latest/developerguide/cognito-identity.html) in the *Amazon Cognito Developer Guide*. | 
| \$1context.identity.cognitoAuthenticationType |  The Amazon Cognito authentication type of the caller making the request. Available only if the request was signed with Amazon Cognito credentials. Possible values include `authenticated` for authenticated identities and `unauthenticated` for unauthenticated identities. | 
| \$1context.identity.cognitoIdentityId |  The Amazon Cognito identity ID of the caller making the request. Available only if the request was signed with Amazon Cognito credentials.  | 
| \$1context.identity.cognitoIdentityPoolId |  The Amazon Cognito identity pool ID of the caller making the request. Available only if the request was signed with Amazon Cognito credentials.  | 
| \$1context.identity.principalOrgId |  The [Amazon organization ID](https://docs.amazonaws.cn/organizations/latest/userguide/orgs_manage_org_details.html). Supported for routes that use IAM authorization.  | 
| \$1context.identity.clientCert.clientCertPem |  The PEM-encoded client certificate that the client presented during mutual TLS authentication. Present when a client accesses an API by using a custom domain name that has mutual TLS enabled.  | 
| \$1context.identity.clientCert.subjectDN |  The distinguished name of the subject of the certificate that a client presents. Present when a client accesses an API by using a custom domain name that has mutual TLS enabled.  | 
| \$1context.identity.clientCert.issuerDN |  The distinguished name of the issuer of the certificate that a client presents. Present when a client accesses an API by using a custom domain name that has mutual TLS enabled.  | 
| \$1context.identity.clientCert.serialNumber |  The serial number of the certificate. Present when a client accesses an API by using a custom domain name that has mutual TLS enabled.  | 
| \$1context.identity.clientCert.validity.notBefore |  The date before which the certificate is invalid. Present when a client accesses an API by using a custom domain name that has mutual TLS enabled.  | 
| \$1context.identity.clientCert.validity.notAfter |  The date after which the certificate is invalid. Present when a client accesses an API by using a custom domain name that has mutual TLS enabled.  | 
| \$1context.identity.sourceIp |  The source IP address of the immediate TCP connection making the request to API Gateway endpoint.  | 
| \$1context.identity.user |  The principal identifier of the user that will be authorized against resource access. Supported for routes that use IAM authorization.  | 
| \$1context.identity.userAgent |  The [https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent) header of the API caller.  | 
| \$1context.identity.userArn |  The Amazon Resource Name (ARN) of the effective user identified after authentication. Supported for routes that use IAM authorization. For more information, see [https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users.html](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users.html).  | 
| \$1context.integration.error | The error message returned from an integration. Equivalent to \$1context.integrationErrorMessage. | 
| \$1context.integration.integrationStatus | For Lambda proxy integration, the status code returned from Amazon Lambda, not from the backend Lambda function code. | 
| \$1context.integration.latency | The integration latency in ms. Equivalent to \$1context.integrationLatency. | 
| \$1context.integration.requestId | The Amazon endpoint's request ID. Equivalent to \$1context.awsEndpointRequestId. | 
| \$1context.integration.status | The status code returned from an integration. For Lambda proxy integrations, this is the status code that your Lambda function code returns. | 
| \$1context.integrationErrorMessage |  A string that contains an integration error message.  | 
| \$1context.integrationLatency | The integration latency in ms. | 
| \$1context.integrationStatus | For Lambda proxy integration, this parameter represents the status code returned from Amazon Lambda, not from the backend Lambda function. | 
| \$1context.path | The request path. For example, /\$1stage\$1/root/child.  | 
| \$1context.protocol | The request protocol, for example, HTTP/1.1.  API Gateway APIs can accept HTTP/2 requests, but API Gateway sends requests to backend integrations using HTTP/1.1. As a result, the request protocol is logged as HTTP/1.1 even if a client sends a request that uses HTTP/2.   | 
| \$1context.requestId |  The ID that API Gateway assigns to the API request.  | 
| \$1context.requestTime | The [CLF](https://httpd.apache.org/docs/current/logs.html#common)-formatted request time (dd/MMM/yyyy:HH:mm:ss \$1-hhmm). | 
| \$1context.requestTimeEpoch | The [Epoch](https://en.wikipedia.org/wiki/Unix_time)-formatted request time. | 
| \$1context.responseLatency | The response latency in ms. | 
| \$1context.responseLength | The response payload length in bytes. | 
| \$1context.routeKey |  The route key of the API request, for example `/pets`.  | 
| \$1context.stage |  The deployment stage of the API request (for example, `beta` or `prod`).  | 
| \$1context.status | The method response status. | 