

# 为 API Gateway 中的 HTTP API 配置日志记录
<a name="http-api-logging"></a>

您可以开启日志记录以将日志写入 CloudWatch Logs。您可以使用[日志记录变量](http-api-logging-variables.md)来自定义日志的内容。

为了改善安全状况，我们建议您将 HTTP API 的所有阶段的日志写入 CloudWatch Logs。为遵守各种合规性框架，您可能需要执行此操作。有关更多信息，请参阅《AWS Security Hub User Guide》**中的 [Amazon API Gateway Controls](https://docs.aws.amazon.com/securityhub/latest/userguide/apigateway-controls.html)。

要为 HTTP API 开启日志记录，您必须执行以下操作。

1. 确保您的用户具有激活日志记录所需的权限。

1. 创建 CloudWatch Logs 日志组。

1. 为 API 的某个阶段提供 CloudWatch Logs 日志组的 ARN。

## 激活日志记录的权限
<a name="http-api-logging.permissions"></a>

要开启 API 的日志记录，您的用户必须具有以下权限。

**Example**    
****  

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

## 创建日志组并激活 HTTP API 的日志记录
<a name="http-api-enable-logging"></a>

您可以使用 AWS 管理控制台 或 AWS CLI 创建日志组并激活访问日志记录。

------
#### [ AWS 管理控制台 ]

1.  创建日志组。

   要了解如何使用控制台建立日志组，请参阅[《Amazon CloudWatch Logs 用户指南》中的“创建日志组”](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/Working-with-log-groups-and-streams.html)。

1. 通过以下网址登录到 Amazon API Gateway 控制台：[https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)。

1. 选择 HTTP API。

1. 在主导航面板的 **Monitor**（监控）选项卡下，选择 **Logging**（日志记录）。

1. 选择要激活日志记录的阶段，然后选择 **Select**（选择）。

1. 选择 **Edit**（编辑）以激活访问日志。

1. 开启 **Access logging**（访问日志），进入 CloudWatch Logs，然后选择日志格式。

1. 选择**保存**。

------
#### [ AWS CLI ]

以下 [create-log-group](https://docs.aws.amazon.com/cli/latest/reference/logs/create-log-group.html) 命令创建日志组：

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

您需要日志组的 Amazon 资源名称（ARN）才能开启日志记录。ARN 格式为 arn:aws:logs:*region*:*account-id*:log-group:*log-group-name*。

以下 [update-stage](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/update-stage.html) 命令为 HTTP API 的 `$default` 阶段开启日志记录：

```
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"}'
```

------

## 日志格式示例
<a name="http-api-enable-logging.examples"></a>

一些常用的访问日志格式的示例在 API Gateway 控制台中显示，下面列出了这些格式。
+ `CLF` ([常用日志格式](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`（逗号分隔值）：

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

# 自定义 HTTP API 访问日志
<a name="http-api-logging-variables"></a>

您可以使用以下变量自定义 HTTP API 访问日志。要了解有关 HTTP API 的访问日志的更多信息，请参阅 [为 API Gateway 中的 HTTP API 配置日志记录](http-api-logging.md)。


| 参数 | 说明 | 
| --- | --- | 
| \$1context.accountId |  API 拥有者的 AWS 账户 ID。  | 
| \$1context.apiId |  API Gateway 分配给您的 API 的标识符。  | 
| \$1context.authorizer.claims.property |  成功对方法调用方进行身份验证后从 JSON Web 令牌（JWT）返回的声明的属性，如 `$context.authorizer.claims.username`。有关更多信息，请参阅 [在 API Gateway 中使用 JWT 授权方控制对 HTTP API 的访问](http-api-jwt-authorizer.md)。  调用 `$context.authorizer.claims` 将返回 null。   | 
| \$1context.authorizer.error | 从授权方返回的错误消息。 | 
| \$1context.authorizer.property |  从 API Gateway Lambda 授权方函数返回的 `context` 映射的指定键/值对的值。例如，如果授权方返回以下 `context` 映射： <pre>"context" : {<br />  "key": "value",<br />  "numKey": 1,<br />  "boolKey": true<br />}</pre> 调用 `$context.authorizer.key` 将返回 `"value"` 字符串，调用 `$context.authorizer.numKey` 将返回 `1`，调用 `$context.authorizer.boolKey` 将返回 `true`。  | 
| \$1context.awsEndpointRequestId |  `x-amz-request-id` 或 `x-amzn-requestId` 标头中AWS端点的请求 ID。  | 
| \$1context.awsEndpointRequestId2 |  来自 `x-amz-id-2` 标头的AWS端点的请求 ID。  | 
| \$1context.customDomain.basePathMatched |  传入请求所匹配的 API 映射路径。适用于客户端使用自定义域名访问 API 的情况。例如，如果客户端向 `https://api.example.com/v1/orders/1234` 发送请求，且该请求匹配路径为 `v1/orders` 的 API 映射，则值为 `v1/orders`。要了解更多信息，请参阅“[将 API 阶段映射到 HTTP API 的自定义域名](http-api-mappings.md)”。  | 
| \$1context.dataProcessed | 处理的数据量（以字节为单位）。 | 
| \$1context.domainName |  用于调用 API 的完整域名。这应与传入的 `Host` 标头相同。  | 
| \$1context.domainPrefix |  `$context.domainName` 的第一个标签。  | 
| \$1context.error.message |  包含 API Gateway 错误消息的字符串。  | 
| \$1context.error.messageString | \$1context.error.message 的带引号的值，即 "\$1context.error.message"。 | 
| \$1context.error.responseType |  一种 `GatewayResponse` 类型。有关更多信息，请参阅 [使用 CloudWatch 指标监控 WebSocket API 执行](apigateway-websocket-api-logging.md) 和 [设置网关响应以自定义错误响应](api-gateway-gatewayResponse-definition.md#customize-gateway-responses)。  | 
| \$1context.extendedRequestId | 等效于 \$1context.requestId。 | 
| \$1context.httpMethod |  所用的 HTTP 方法。有效值包括：`DELETE`、`GET`、`HEAD`、`OPTIONS`、`PATCH`、`POST` 和 `PUT`。  | 
| \$1context.identity.accountId |  与请求关联的 AWS 账户 ID。对于使用 IAM 授权的路由支持此项。  | 
| \$1context.identity.caller |  签发请求的调用方的委托人标识符。对于使用 IAM 授权的路由支持此项。  | 
| \$1context.identity.cognitoAuthenticationProvider |  发出请求的调用方使用的所有 Amazon Cognito 身份验证提供商的逗号分隔列表。仅当使用 Amazon Cognito 凭证对请求签名时才可用。 例如，对于 Amazon Cognito 身份池中的身份，`cognito-idp. region.amazonaws.com/user_pool_id,cognito-idp.region.amazonaws.com/user_pool_id:CognitoSignIn:token subject claim` 有关更多信息，请参阅 *Amazon Cognito 开发人员指南* 中的[使用联合身份](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-identity.html)。 | 
| \$1context.identity.cognitoAuthenticationType |  发出请求的调用方的 Amazon Cognito 身份验证类型。仅当使用 Amazon Cognito 凭证对请求签名时才可用。可能的值包括经过身份验证的身份的 `authenticated` 和未经身份验证的身份的 `unauthenticated`。 | 
| \$1context.identity.cognitoIdentityId |  发出请求的调用方的 Amazon Cognito 身份 ID。仅当使用 Amazon Cognito 凭证对请求签名时才可用。  | 
| \$1context.identity.cognitoIdentityPoolId |  发出请求的调用方的 Amazon Cognito 身份池 ID。仅当使用 Amazon Cognito 凭证对请求签名时才可用。  | 
| \$1context.identity.principalOrgId |  [AWS 组织 ID](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_org_details.html)。对于使用 IAM 授权的路由支持此项。  | 
| \$1context.identity.clientCert.clientCertPem |  客户端在双向 TLS 身份验证过程中提供的 PEM 编码的客户端证书。当客户端使用已启用双向 TLS 的自定义域名访问 API 时提供。  | 
| \$1context.identity.clientCert.subjectDN |  客户端提供的证书的主题的可分辨名称。当客户端使用已启用双向 TLS 的自定义域名访问 API 时提供。  | 
| \$1context.identity.clientCert.issuerDN |  客户端提供的证书的颁发者的可分辨名称。当客户端使用已启用双向 TLS 的自定义域名访问 API 时提供。  | 
| \$1context.identity.clientCert.serialNumber |  证书的序列号。当客户端使用已启用双向 TLS 的自定义域名访问 API 时提供。  | 
| \$1context.identity.clientCert.validity.notBefore |  证书无效之前的日期。当客户端使用已启用双向 TLS 的自定义域名访问 API 时提供。  | 
| \$1context.identity.clientCert.validity.notAfter |  证书无效后的日期。当客户端使用已启用双向 TLS 的自定义域名访问 API 时提供。  | 
| \$1context.identity.sourceIp |  向 API Gateway 端点发出请求的即时 TCP 连接的源 IP 地址。  | 
| \$1context.identity.user |  将获得资源访问权限授权的用户的委托人标识符。对于使用 IAM 授权的路由支持此项。  | 
| \$1context.identity.userAgent |  API 调用方的 [https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent) 标头。  | 
| \$1context.identity.userArn |  身份验证后标识的有效用户的 Amazon Resource Name (ARN)。对于使用 IAM 授权的路由支持此项。有关更多信息，请参阅 [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 | 从集成返回的错误消息。等效于 \$1context.integrationErrorMessage。 | 
| \$1context.integration.integrationStatus | 对于 Lambda 代理集成，从 AWS Lambda（而不是从后端 Lambda 函数代码）返回的状态代码。 | 
| \$1context.integration.latency | 集成延迟（毫秒）。等效于 \$1context.integrationLatency。 | 
| \$1context.integration.requestId | AWS 端点的请求 ID。等效于 \$1context.awsEndpointRequestId。 | 
| \$1context.integration.status | 从集成返回的状态代码。对于 Lambda 代理集成，这是 Lambda 函数代码返回的状态代码。 | 
| \$1context.integrationErrorMessage |  包含集成错误消息的字符串。  | 
| \$1context.integrationLatency | 集成延迟（毫秒）。 | 
| \$1context.integrationStatus | 对于 Lambda 代理集成，此参数表示从 AWS Lambda（而不是从后端 Lambda 函数）返回的状态代码。 | 
| \$1context.path | 请求路径。例如：/\$1stage\$1/root/child。 | 
| \$1context.protocol | 请求的协议，例如，HTTP/1.1。 API Gateway API 可以接受 HTTP/2 请求，但 API Gateway 使用 HTTP/1.1 向后端集成发送请求。因此，即使客户端发送的请求使用 HTTP/2，请求协议也会记录为 HTTP/1.1。   | 
| \$1context.requestId |  API Gateway 分配给 API 请求的 ID。  | 
| \$1context.requestTime | [CLF](https://httpd.apache.org/docs/current/logs.html#common) 格式的请求时间 (dd/MMM/yyyy:HH:mm:ss \$1-hhmm)。 | 
| \$1context.requestTimeEpoch | [Epoch](https://en.wikipedia.org/wiki/Unix_time) 格式的请求时间。 | 
| \$1context.responseLatency | 响应延迟（毫秒）。 | 
| \$1context.responseLength | 响应负载长度（以字节为单位）。 | 
| \$1context.routeKey |  API 请求的路由密钥，例如 `/pets`。  | 
| \$1context.stage |  API 请求的部署阶段（例如，`beta` 或 `prod`）。  | 
| \$1context.status | 方法响应状态。 | 