在 API Gateway 中为 REST API 设置 CloudWatch 日志记录 - Amazon API Gateway
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

在 API Gateway 中为 REST API 设置 CloudWatch 日志记录

为了帮助调试与请求执行或客户端对 API 的访问的相关问题,您可以启用 Amazon CloudWatch Logs 以记录 API 调用。有关 CloudWatch 的更多信息,请参阅使用 Amazon CloudWatch 指标监控 REST API 执行

用于 API Gateway 的 CloudWatch 日志格式

在 CloudWatch 中有两种类型的 API 日志记录:执行日志记录和访问日志记录。在执行日志记录中,API Gateway 管理 CloudWatch Logs。该过程包括创建日志组和日志流,以及向日志流报告任意调用方的请求和响应。

记录的数据包括错误或执行跟踪(例如请求或响应的参数值或负载)、Lambda 授权方(以前称为自定义授权方)使用的数据、是否需要 API 密钥、是否启用了使用计划等等。

部署 API 时,API Gateway 创建日志组和日志组下的日志流。日志组以 API-Gateway-Execution-Logs_{rest-api-id}/{stage_name} 格式命名。在每个日志组内,日志进一步划分到日志流中,后者在报告记录的数据时按照 Last Event Time (上次事件时间) 排序。

在访问日志记录中,作为 API 开发人员,您想要记录谁访问了您的 API 以及调用方访问 API 的方式。您可以创建自己的日志组,或者选择可由 API Gateway 管理的现有日志组。要指定访问详细信息,您可以选择 $context 变量(以您选择的格式表示),并选择日志组作为目标。访问日志格式必须至少包括 $context.requestId$context.extendedRequestId。作为最佳实践,以日志格式包含 $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 是 API Gateway 生成的唯一 ID。API Gateway 返回 x-amz-apigw-id 响应标头中的此请求 ID。API 调用者无法提供或覆盖此请求 ID。有关更多信息,请参阅$context数据模型、授权者、映射模板和 CloudWatch 访问日志的变量

注意

仅支持 $context 变量(而不支持 $input 等)。

选择您的分析后端也采用的日志格式,例如常用日志格式 (CLF)、JSON、XML 或 CSV。然后,您可以将访问日志直接输送到其中,以计算和呈现您的指标。要定义日志格式,请在阶段accessLogSettings/destinationArn 属性上设置日志组 ARN。您可以在 CloudWatch 控制台中获取日志组 ARN,前提是选择了要显示的 ARN 列。要定义访问日志格式,请在阶段accessLogSetting/format 属性上设置选定格式。

一些常用访问日志格式的示例在 API Gateway 控制台中显示,下面列出了这些格式。

  • CLF (常用日志格式 ):

    $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

    继续符 (\) 用作视觉辅助。日志格式必须为单行。您可以在日志格式末尾添加换行符 (\n),以便在每个日志条目末尾添加换行符。

  • 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" \ }

    继续符 (\) 用作视觉辅助。日志格式必须为单行。您可以在日志格式末尾添加换行符 (\n),以便在每个日志条目末尾添加换行符。

  • 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>

    继续符 (\) 用作视觉辅助。日志格式必须为单行。您可以在日志格式末尾添加换行符 (\n),以便在每个日志条目末尾添加换行符。

  • 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

    继续符 (\) 用作视觉辅助。日志格式必须为单行。您可以在日志格式末尾添加换行符 (\n),以便在每个日志条目末尾添加换行符。

CloudWatch 日志记录的权限

要启用 CloudWatch Logs,您必须向 API Gateway 授予权限,才能针对您的账户读取日志和将日志写入到 CloudWatch。AmazonAPIGatewayPushToCloudWatchLogs托管策略(ARN 为 arn:aws:iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs)具有全部必需的权限:

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:DescribeLogGroups", "logs:DescribeLogStreams", "logs:PutLogEvents", "logs:GetLogEvents", "logs:FilterLogEvents" ], "Resource": "*" } ] }
注意

API Gateway 将调用 Amazon Security Token Service 以恢复 IAM 角色,因此请确保已为区域启用 Amazon STS。有关更多信息,请参阅在Amazon区域中管理Amazon STS

要将这些权限授予您的账户,请使用 apigateway.amazonaws.com 作为其可信实体创建一个 IAM 角色,将之前的策略附加到此 IAM 角色,然后在您账户cloudWatchRoleArn 属性上设置 IAM 角色 ARN。您必须为要在其中启用 CloudWatch Logs 的每个Amazon区域单独设置 cloudWatchRoleArn 属性。

如果您在设置 IAM 角色 ARN 时收到错误,请检查您的 Amazon Security Token Service 账户设置,以确保在您所使用的区域中启用了 Amazon STS。有关启用 Amazon STS 的更多信息,请参阅 IAM 用户指南中的在Amazon区域中管理Amazon STS

使用 API Gateway 控制台设置 CloudWatch API 日志记录

要设置 CloudWatch API 日志记录,您必须已经将 API 部署到某个阶段。您还必须已经为账户配置了合适的 CloudWatch Logs 角色 ARN。

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

  2. 在主导航窗格上选择设置,然后在日志记录下选择编辑

  3. 对于 CloudWatch 日志角色 ARN,输入具有相应权限的 IAM 角色的 ARN。对于每个使用 API Gateway 创建 API 的 Amazon Web Services 账户,您都需要执行一次此操作。

  4. 在主导航窗格中,选择 API,然后执行以下操作之一:

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

    2. 创建 API,然后将其部署到阶段。

  5. 在主导航窗格中,选择阶段

  6. 日志和跟踪部分中,选择编辑

  7. 启用执行日志记录:

    1. CloudWatch Logs 下拉菜单中选择日志记录级别。

      警告

      完整请求和响应日志对于排除 API 故障非常有用,但可能会导致记录敏感数据。我们建议不要为生产 API 使用完整请求和响应日志

    2. 如果需要,请选择详细指标以开启详细的 CloudWatch 指标。

    有关 CloudWatch 指标的更多信息,请参阅使用 Amazon CloudWatch 指标监控 REST API 执行

  8. 启用访问日志记录:

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

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

    3. 对于日志格式,输入日志格式。您可以选择 CLFJSONXMLCSV。要了解有关示例日志格式的更多信息,请参阅用于 API Gateway 的 CloudWatch 日志格式

  9. 选择保存更改

注意

您可以分别启用执行日志记录和访问日志记录,这两者相互独立。

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

使用 Amazon CloudFormation 设置 CloudWatch API 日志记录

使用以下示例 Amazon CloudFormation 模板创建 Amazon CloudWatch Logs 日志组并配置阶段的执行和访问日志记录。要启用 CloudWatch Logs,您必须向 API Gateway 授予权限,才能针对您的账户读取日志和将日志写入到 CloudWatch。要了解更多信息,请参阅《Amazon CloudFormation 用户指南》中的将账户与 IAM 角色关联

TestStage: Type: AWS::ApiGateway::Stage Properties: StageName: test RestApiId: !Ref MyAPI DeploymentId: !Ref Deployment Description: "test stage description" MethodSettings: - ResourcePath: "/*" HttpMethod: "*" LoggingLevel: INFO 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