

# REST API 的访问日志记录
<a name="set-up-access-logging"></a>

在访问日志记录中，您可以记录谁访问了您的 API 以及调用方访问 API 的方式。您可以创建自己的日志组，也可以选择现有日志组。要指定访问详细信息，可以选择 [`$context`](api-gateway-variables-for-access-logging.md) 变量、日志格式和日志组目标。

## 访问日志格式
<a name="apigateway-cloudwatch-log-formats"></a>

访问日志格式必须至少包括 `$context.requestId` 或 `$context.extendedRequestId`。作为最佳实践，请在日志格式中同时包含两者。

**`$context.requestId`**  
这会将值记录在 `x-amzn-RequestId` 标头中。客户端可以用通用唯一标识符 (UUID) 格式的值覆盖 `x-amzn-RequestId` 标头中的值。API Gateway 返回 `x-amzn-RequestId` 响应标头中的此请求 ID。API Gateway 将不采用 UUID 格式的被覆盖的请求 ID 替换为访问日志中的 `{{UUID}}_REPLACED_INVALID_REQUEST_ID`。

**`$context.extendedRequestId`**  
extendedRequestID 是 API Gateway 生成的唯一 ID。API Gateway 返回 `x-amz-apigw-id` 响应标头中的此请求 ID。API 调用者无法提供或覆盖此请求 ID。您可能需要向 Amazon Support 提供此值，来协助排查 API 的问题。有关更多信息，请参阅 [API Gateway 的访问日志记录的变量](api-gateway-variables-for-access-logging.md)。

选择您的分析后端也采用的日志格式，例如[常用日志格式](https://httpd.apache.org/docs/current/logs.html#common) (CLF)、JSON、XML 或 CSV。然后，您可以将访问日志直接输送到其中，以计算和呈现您的指标。要定义日志格式，请在[阶段](https://docs.amazonaws.cn/apigateway/latest/api/API_Stage.html)的 [accessLogSettings/destinationArn](https://docs.amazonaws.cn/apigateway/latest/api/API_Stage.html#destinationArn) 属性上设置日志组 ARN。您可以在 CloudWatch 控制台中获取日志组 ARN。要定义访问日志格式，请在[阶段](https://docs.amazonaws.cn/apigateway/latest/api/API_Stage.html)的 [accessLogSetting/format](https://docs.amazonaws.cn/apigateway/latest/api/API_Stage.html#format) 属性上设置选定格式。

一些常用访问日志格式的示例在 API Gateway 控制台中显示，下面列出了这些格式。
+ `CLF`（[常用日志格式](https://httpd.apache.org/docs/current/logs.html#common)）：

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

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

  ```
  <request id="$context.requestId"> <extendedRequestId>$context.extendedRequestId</extendedRequestId> <ip>$context.identity.sourceIp</ip> <caller>$context.identity.caller</caller> <user>$context.identity.user</user> <requestTime>$context.requestTime</requestTime> <httpMethod>$context.httpMethod</httpMethod> <resourcePath>$context.resourcePath</resourcePath> <status>$context.status</status> <protocol>$context.protocol</protocol> <responseLength>$context.responseLength</responseLength> </request>
  ```
+ `CSV`（逗号分隔值）：

  ```
  $context.identity.sourceIp,$context.identity.caller,$context.identity.user,$context.requestTime,$context.httpMethod,$context.resourcePath,$context.protocol,$context.status,$context.responseLength,$context.requestId,$context.extendedRequestId
  ```

## 使用 API Gateway 控制台设置访问日志记录
<a name="set-up-access-logging-using-console"></a>

在设置访问日志记录之前，请将 API 部署到某个阶段，并为您的账户配置[相应的 CloudWatch Logs 角色](set-up-logging.md#set-up-access-logging-permissions) ARN。

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

1. 在主导航窗格中，选择 **API**，然后执行以下操作之一：

   1. 选择现有 API，然后选择一个阶段。

   1. 创建 API，然后将其部署到阶段。

1. 在主导航窗格中，选择**阶段**。

1. 在**日志和跟踪**部分中，选择**编辑**。

1. 开启**自定义访问日志记录**。

1. 对于**访问日志目标 ARN**，输入日志组的 ARN。ARN 格式为 `arn:aws:logs:{{{region}}}:{{{account-id}}}:log-group:{{log-group-name}}`。

1. 对于**日志格式**，输入日志格式。您可以选择 **CLF**、**JSON**、**XML** 或 **CSV**。要了解有关示例日志格式的更多信息，请参阅[访问日志格式](#apigateway-cloudwatch-log-formats)。

1. 选择**保存更改**。

API Gateway 现已准备好记录对您 API 的请求。在更新阶段设置、日志或阶段变量时，您无需重新部署 API。

## 使用 Amazon CloudFormation 设置访问日志记录
<a name="set-up-access-logging-using-cloudformation"></a>

使用以下示例 Amazon CloudFormation 模板创建 Amazon CloudWatch Logs 日志组并配置阶段的访问日志记录。要启用 CloudWatch Logs，您必须向 API Gateway 授予权限，才能针对您的账户读取日志和将日志写入到 CloudWatch。要了解更多信息，请参阅《Amazon CloudFormation 用户指南》**中的[将账户与 IAM 角色关联](https://docs.amazonaws.cn/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-account.html#aws-resource-apigateway-account--examples)。

```
  TestStage:
    Type: AWS::ApiGateway::Stage
    Properties:
      StageName: test
      RestApiId: !Ref MyAPI
      DeploymentId: !Ref Deployment
      AccessLogSetting:
        DestinationArn: !GetAtt MyLogGroup.Arn
        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
  MyLogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Join
        - '-'
        - - !Ref MyAPI
          - access-logs
```