

# 监控 API Gateway 中的 WebSocket API
<a name="websocket-api-monitor"></a>

您可以使用 CloudWatch 指标和 CloudWatch Logs 来监控 WebSocket API。通过合并日志和指标，您可以记录错误并监控 API 的性能。

**注意**  
在以下情况下，API Gateway 可能无法生成日志和指标：  
“413 请求实体过大”错误
过多的“429 请求太多”错误
发送到没有 API 映射的自定义域的请求中出现 400 系列错误
由内部故障造成的 500 系列错误

**Topics**
+ [使用 CloudWatch 指标监控 WebSocket API 执行](apigateway-websocket-api-logging.md)
+ [为 API Gateway 中的 WebSocket API 配置日志记录](websocket-api-logging.md)

# 使用 CloudWatch 指标监控 WebSocket API 执行
<a name="apigateway-websocket-api-logging"></a>

您可以使用 [Amazon CloudWatch](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/WhatIsCloudWatch.html) 指标来监控 WebSocket API。该配置类似于 REST API 使用的配置。有关更多信息，请参阅 [使用 Amazon CloudWatch 指标监控 REST API 执行](monitoring-cloudwatch.md)。

WebSocket API 支持以下指标：


| 指标 | 说明 | 
| --- | --- | 
| ConnectCount | 发送到 \$1connect 路由集成的消息数。 | 
| MessageCount | 从客户端发送到 WebSocket API 的消息数。 | 
| IntegrationError | 从集成返回 4XX/5XX 响应的请求数。 | 
| ClientError | 在调用集成之前由 API Gateway 返回 4XX 响应的请求数。 | 
| ExecutionError | 调用集成时发生的错误。 | 
| IntegrationLatency | API Gateway 向集成发送请求和 API Gateway 从集成接收响应之间的时间差。已对回调和模拟集成禁止。 | 

您可以使用下表中的维度筛选 API Gateway 指标。


| 维度 | 说明 | 
| --- | --- | 
| ApiId | 筛选具有指定 API ID 的 API 的 API Gateway 指标。 | 
| ApiId、阶段 | 针对具有指定 API ID 和阶段 ID 的 API 阶段筛选 API Gateway 指标。 | 
| ApiId、方法、资源、阶段 |  使用指定的 API ID、阶段 ID、资源路径和路由 ID 筛选 API 方法的 API Gateway 指标。 除非您明确启用了详细的 CloudWatch 指标，否则 API Gateway 不会发送这些指标。要执行此操作，您可以通过调用 API Gateway V2 REST API 的 [UpdateStage](https://docs.aws.amazon.com/apigatewayv2/latest/api-reference/apis-apiid-stages-stagename.html) 操作，将 `detailedMetricsEnabled` 属性更新为 `true`。或者，您也可以调用 [update-stage](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/update-stage.html) AWS CLI 命令，以将 `DetailedMetricsEnabled` 属性更新为 `true`。启用这些指标会对您的账户额外计费。有关定价信息，请参阅 [Amazon CloudWatch 定价](https://aws.amazon.com/cloudwatch/pricing/)。  | 

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

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

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

在访问日志记录中，作为 API 开发人员，您想要记录谁访问了您的 API 以及调用方访问 API 的方式。您可以创建自己的日志组，或者选择可由 API Gateway 管理的现有日志组。要指定访问详细信息，您可以选择 `$context` 变量（以您选择的格式表示），并选择日志组作为目标。

有关如何设置 CloudWatch 日志记录的说明，请参阅[使用 API Gateway 控制台设置 CloudWatch API 日志记录](set-up-logging.md#set-up-access-logging-using-console)。

当您指定 **Log Format (日志格式)** 时，您可以选择要记录的上下文变量。支持以下变量。


| 参数 | 说明 | 
| --- | --- | 
| \$1context.apiId |  API Gateway 分配给您的 API 的标识符。  | 
| \$1context.authorize.error | 授权错误消息。 | 
| \$1context.authorize.latency | 授权延迟时间（以毫秒为单位）。 | 
| \$1context.authorize.status | 从授权尝试返回的状态代码。 | 
| \$1context.authorizer.error | 从授权方返回的错误消息。 | 
| \$1context.authorizer.integrationLatency | Lambda 授权方延迟（以毫秒为单位）。 | 
| \$1context.authorizer.integrationStatus | 从 Lambda 授权方返回的状态代码。 | 
| \$1context.authorizer.latency | 授权方延迟（以毫秒为单位）。 | 
| \$1context.authorizer.requestId | AWS 端点的请求 ID。 | 
| \$1context.authorizer.status | 从授权方返回的状态代码。 | 
| \$1context.authorizer.principalId |  与由客户端发送的令牌相关联的委托人用户标识，从API Gateway Lambda 授权方 Lambda 函数返回。（Lambda 授权方以前称为自定义授权方。）  | 
| \$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.authenticate.error | 从身份验证尝试返回的错误消息。 | 
| \$1context.authenticate.latency | 身份验证延迟时间（以毫秒为单位）。 | 
| \$1context.authenticate.status | 从身份验证尝试返回的状态代码。 | 
| \$1context.connectedAt |  [Epoch](https://en.wikipedia.org/wiki/Unix_time) 格式的连接时间。  | 
| \$1context.connectionId |  连接的唯一 ID，可用于对客户端进行回调。  | 
| \$1context.domainName |  WebSocket API 的域名。这可用于对客户端进行回调（而不是硬编码值）。  | 
| \$1context.error.message |  包含 API Gateway 错误消息的字符串。  | 
| \$1context.error.messageString | \$1context.error.message 的带引号的值，即 "\$1context.error.message"。 | 
| \$1context.error.responseType |  错误响应类型。  | 
| \$1context.error.validationErrorString |  包含详细验证错误消息的字符串。  | 
| \$1context.eventType |  事件类型：`CONNECT`、`MESSAGE` 或 `DISCONNECT`。  | 
| \$1context.extendedRequestId | 等效于 \$1context.requestId。 | 
| \$1context.identity.accountId |  与请求关联的 AWS 账户 ID。  | 
| \$1context.identity.apiKey |  API 所有者密钥与启用密钥的 API 请求关联。  | 
| \$1context.identity.apiKeyId | API 密钥 ID 与启用密钥的 API 请求关联 | 
| \$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.sourceIp |  向 API Gateway 发出请求的 TCP 连接的源 IP 地址。  | 
| \$1context.identity.user |  将获得资源访问权限授权的用户的委托人标识符。对于使用 IAM 授权的路由支持此项。  | 
| \$1context.identity.userAgent |  API 调用方的用户代理。  | 
| \$1context.identity.userArn |  身份验证后标识的有效用户的 Amazon 资源名称 (ARN)。  | 
| \$1context.integration.error | 从集成返回的错误消息。 | 
| \$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.integrationStatus。 | 
| \$1context.integrationLatency | 集成延迟（毫秒），仅可用于访问日志记录。 | 
| \$1context.messageId |  消息的唯一服务器端 ID。仅当 `$context.eventType` 为 `MESSAGE` 时才可用。  | 
| \$1context.requestId |  与 `$context.extendedRequestId` 相同。  | 
| \$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.routeKey |  选定的路由键。  | 
| \$1context.stage |  API 调用的部署阶段（例如测试或生产）。  | 
| \$1context.status |  响应状态。  | 
| \$1context.waf.error | 从 返回的错误消息AWS WAF | 
| \$1context.waf.latency | AWS WAF 延迟时间（以毫秒为单位） | 
| \$1context.waf.status | 从 返回的状态代码AWS WAF | 

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

  ```
  $context.identity.sourceIp $context.identity.caller \
  $context.identity.user [$context.requestTime] "$context.eventType $context.routeKey $context.connectionId" \
  $context.status $context.requestId
  ```

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

  ```
  {
  "requestId":"$context.requestId", \
  "ip": "$context.identity.sourceIp", \
  "caller":"$context.identity.caller", \
  "user":"$context.identity.user", \
  "requestTime":"$context.requestTime", \
  "eventType":"$context.eventType", \
  "routeKey":"$context.routeKey", \
  "status":"$context.status", \
  "connectionId":"$context.connectionId"
  }
  ```

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

  ```
  <request id="$context.requestId"> \
   <ip>$context.identity.sourceIp</ip> \
   <caller>$context.identity.caller</caller> \
   <user>$context.identity.user</user> \
   <requestTime>$context.requestTime</requestTime> \
   <eventType>$context.eventType</eventType> \
   <routeKey>$context.routeKey</routeKey> \
   <status>$context.status</status> \
   <connectionId>$context.connectionId</connectionId> \
  </request>
  ```

  继续符 (`\`) 用作视觉辅助。日志格式必须为单行。您可以在日志格式末尾添加换行符 (`\n`)，以便在每个日志条目末尾添加换行符。
+ `CSV` (逗号分隔值)：

  ```
  $context.identity.sourceIp,$context.identity.caller, \
  $context.identity.user,$context.requestTime,$context.eventType, \
  $context.routeKey,$context.connectionId,$context.status, \
  $context.requestId
  ```

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