监控和日志记录 - AWS AppSync
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 AWS 服务入门

监控和日志记录

您可以使用 Amazon CloudWatch 监控和调试 AWS AppSync 中的请求。通过 AWS AppSync,您可以使用 GraphQL 从云中请求数据。很多时候,您希望获得有关 API 执行情况的更多信息。为了帮助调试与 GraphQL API 的请求执行相关的问题,您可以启用 Amazon CloudWatch Logs 以监控 API 调用。通过 CloudWatch 启用后,AWS AppSync 将在 CloudWatch 中记录 API 调用。

设置和配置

您可以通过 AWS AppSync 控制台自动对 GraphQL API 启用日志记录。

  1. 登录到 AWS AppSync 控制台。

  2. 从导航面板中选择 Settings (设置)

  3. Logging (日志记录)下,单击以切换到 Enable Logs (启用日志)

  4. 当控制台提示您时,提供或创建 CloudWatch ARN 角色。

  5. (可选)从列表中选择以配置字段解析程序日志级别。

  6. 选择 Save。将自动为您的 API 配置日志记录。

手动角色配置

要启用 CloudWatch Logs,您必须授予 AWS AppSync 正确的权限,以在您账户的 CloudWatch 中写入日志。为此,您需要提供一个服务角色 ARN,以便 AWS AppSync 在写入日志时可以使用此角色。

首先,导航到 IAM 控制台。然后,使用名称 AWSAppSyncPushToCloudWatchLogsPolicy 创建新策略,此策略具有以下定义:

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents" ], "Resource": "*" } ] }

接下来,使用名称 AWSAppSyncPushToCloudWatchLogsRole 创建新的角色,然后将上述策略附加到此角色。编辑此角色的信任关系以具有以下内容:

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "appsync.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }

复制角色 ARN 并向 AWS AppSync 注册此 ARN,以启用写入 CloudWatch。

CloudWatch 指标

您可以使用 CloudWatch 指标来监控并提供有关特定事件的提醒,这些事件可能是由 HTTP 状态代码或延迟触发的,例如总体 GraphQL 请求和响应延迟。以下是发出的指标。

  • 4XX

    由于客户端配置不正确,导致请求无效而捕获的错误数。通常,这些错误在 GraphQL 执行之外的任意位置发生。例如,当请求包含不正确的 JSON 负载或不正确的查询、服务受到限制或身份验证设置出现配置错误时,可能会发生此错误。

    单位计数。使用 Sum 统计数据以得出这些错误的总出现次数。

  • 5XX

    在执行 GraphQL 查询期间遇到的错误。例如,当对空或不正确的架构发起查询请求时,可能发生这种错误。当 Amazon Cognito 用户池 ID 或 AWS 区域无效时,也可能发生这种错误。或者,如果 AWS AppSync 在执行请求的过程中遇到问题,也会发生此类错误。

    单位计数。使用 Sum 统计数据以得出这些错误的总出现次数。

  • 延迟

    从 AWS AppSync 从客户端收到请求到其将响应返回给客户端所经过的时间。这不包括响应进入终端设备所遇到的网络延迟。

    单位毫秒。使用平均值统计数据可评估预期延迟。

实时订阅

所有指标都在一个维度中发出:GraphQLAPIId。这意味着所有指标都与 GraphQL API ID 相结合。以下指标与纯 WebSocket 上的 GrapQL 订阅相关:

  • ConnectSuccess

    到 AWS AppSync 的 WebSocket 成功连接数。可以在没有订阅的情况下进行连接。

    单位计数。使用 Sum 统计数据可得出成功连接的总出现次数。

  • ConnectClientError

    由于客户端错误而被 AWS AppSync 拒绝的 WebSocket 连接数。这可能意味着服务受到限制或授权设置出现配置错误。

    单位计数。使用 Sum 统计数据以得出客户端连接错误的总出现次数。

  • ConnectServerError

    处理连接时源自 AWS AppSync 的错误数。当出现意外的服务器端问题时,通常会发生这种错误。

    单位计数。使用 Sum 统计数据以得出服务器端连接错误的总出现次数。

  • DisconnectSuccess

    来自 AWS AppSync 的成功的 WebSocket 断开连接数。

    单位计数。使用 Sum 统计数据可得出成功断开连接的总出现次数。

  • DisconnectError

    断开 WebSocket 连接时源自 AWS AppSync 的错误数。

    单位计数。使用 Sum 统计数据可得出断开连接错误的总出现次数。

  • SubscribeSuccess

    通过 WebSocket 成功注册到 AWS AppSync 的订阅数。可以在没有订阅的情况下建立连接,但无法在没有连接的情况下进行订阅。

    单位计数。使用 Sum 统计数据以得出成功订阅的总发生次数。

  • SubscribeClientError

    由于客户端错误而被 AWS AppSync 拒绝的订阅数。当 JSON 负载不正确、服务受到限制或授权设置出现配置错误时,可能会发生这种错误。

    单位计数。使用 Sum 统计数据以得出客户端订阅错误的总出现次数。

  • SubscribeServerError

    处理订阅时源自 AWS AppSync 的错误数。当出现意外的服务器端问题时,通常会发生这种错误。

    单位计数。使用 Sum 统计数据以得出服务器端订阅错误的总出现次数。

  • UnsubscribeSuccess

    已从 AWS AppSync 成功处理的取消订阅数量。

    单位计数。使用 Sum 统计数据以得出成功取消订阅的总发生次数。

  • UnsubscribeClientError

    由于客户端错误而被 AWS AppSync 拒绝的取消订阅数。

    单位计数。使用 Sum 统计数据以得出客户端取消订阅错误的总出现次数。

  • UnsubscribeServerError

    处理取消订阅时源自 AWS AppSync 的错误数。当出现意外的服务器端问题时,通常会发生这种错误。

    单位计数。使用 Sum 统计数据以得出服务器端取消订阅错误的总出现次数。

  • PublishDataMessageSuccess

    已成功发布的订阅事件消息的数量。

    单位计数。使用 Sum 统计数据以得出成功发布的订阅事件消息的总数。

  • PublishDataMessageClientError

    由于客户端错误而无法发布的订阅事件消息的数量。

    单位计数。使用 Sum 统计数据以得出客户端发布订阅事件错误的总出现次数。

  • PublishDataMessageServerError

    发布订阅事件消息时源自 AWS AppSync 的错误数。当出现意外的服务器端问题时,通常会发生这种错误。

    单位计数。使用 Sum 统计数据以得出服务器端发布订阅事件错误的总出现次数。

  • PublishDataMessageSize

    已发布的订阅事件消息的大小。

    单位字节

  • ActiveConnection

    1 分钟内从客户端到 AWS AppSync 的并发 WebSocket 连接的数量。

    单位计数。使用 Sum 统计数据以得出建立的连接总数。

  • ActiveSubscription

    1 分钟内来自客户端的并发订阅数。

    单位计数。使用 Sum 统计数据以得出有效订阅的总数。

  • ConnectionDuration

    连接保持打开状态的时间量。

    单位毫秒。使用 Average 统计数据可评估连接持续时间。

CloudWatch Logs

您可以对任何新的或现有的 GraphQL API 配置两种类型的日志记录:请求级别和字段级别。

请求级别日志

启用时,系统会记录以下信息:

  • 请求和响应 HTTP 标头

  • 请求中正在执行的 GraphQL 查询

  • 整体执行摘要

  • 已注册的新的和现有的 GraphQL 订阅

字段级别日志

启用时,系统会记录以下信息:

  • 生成的请求映射以及每个字段的源和参数

  • 每个字段的转换后的响应映射,其中包括作为解析该字段的结果的数据

  • 每个字段的跟踪信息

如果您开启日志记录,AWS AppSync 将管理 CloudWatch Logs。该过程包括创建日志组和日志流,以及向日志流报告这些日志。

当您对 GraphQL API 启用日志记录并发起请求时,AWS AppSync 会创建一个日志组并在该日志组中创建日志流。日志组以 /aws/appsync/apis/{graphql_api_id} 格式命名。在每个日志组内,日志会进一步分成多个日志流。当报告已记录的数据时,这些日志按上次事件时间排序。

每个日志事件都用该请求的 x-amzn-RequestId 进行标记。这有助于您在 CloudWatch 中筛选日志事件,以获取与该请求相关的所有已记录的信息。您可以从每个 GraphQL AWS AppSync 请求的响应标头中获取 RequestId。

字段级别日志记录配置为使用以下日志级别:

  • – 未捕获任何字段级别的日志。

  • 错误针对出现错误的字段记录以下信息:
    • 服务器响应中的错误部分

    • 字段级别错误

    • 所生成的请求/响应函数,已针对错误字段获得解析

  • 全部 – 针对查询中的所有字段记录以下信息:
    • 字段级别跟踪信息

    • 所生成的请求/响应函数,已针对每个字段获得解析

启用监控的优势

您可以使用日志记录和指标来识别、优化 GraphQL 查询和排除其问题。例如,这些将帮助您使用针对查询中的每个字段记录的跟踪信息调试延迟问题。为了对此进行演示,假设您正在使用一个或多个嵌套在 GraphQL 查询中的解析程序。CloudWatch Logs 中的示例字段执行可能类似于以下内容:

{ "path": [ "singlePost", "authors", 0, "name" ], "parentType": "Post", "returnType": "String!", "fieldName": "name", "startOffset": 416563350, "duration": 11247 }

这可能对应于 GraphQL 架构,类似于以下内容:

type Post { id: ID! name: String! authors: [Author] } type Author { id: ID! name: String! } type Query { singlePost(id:ID!): Post }

在上面的日志结果中,path 显示从运行名为 singlePost() 的查询所返回的数据中的单个项目。在本例中,它表示位于第一个索引 (0) 处的 name 字段。startOffset 给出 GraphQL 查询执行开始时的偏移量。duration 是解析该字段的总时间。这些值可用来排除下面这类问题:为何来自特定数据源的数据的运行速度可能低于预期,或者特定字段是否降低了整个查询的速度等。例如,您可能选择增加 Amazon DynamoDB 表的预配置吞吐量,或者从查询中删除导致整体执行效果不佳的某个字段。

截至 2019 年 5 月 8 日,AWS AppSync 生成日志事件为完全结构化的 JSON。这使您能够使用日志分析服务(如 Amazon CloudWatch Logs Insights 和 Amazon Elasticsearch Service)以了解 GraphQL 请求的性能和架构字段的使用特征。例如,您可以轻松识别具有较大延迟的解析程序,这可能是导致性能问题的根本原因。您还可以识别架构中最常用和最不常用的字段,并评估弃用 GraphQL 字段的影响。

冲突检测和同步日志记录

如果 AWS AppSync API 已启用 CloudWatch Logs,并将日志记录设置“字段级日志”设为 enabled,将“字段级日志”的日志级别设为 ALL,则 AWS AppSync 会向日志组发送冲突检测和解决信息。这将为 AWS AppSync API 在检测到冲突时决定采取哪些决策提供细致的见解。为此,将在日志中提供以下信息:

conflictType

详细说明是否由于版本不匹配或由于客户提供的状况而发生冲突。

conflictHandlerConfigured

说明请求时在解析程序上配置了冲突处理程序。

message

提供有关如何检测和解决冲突的信息。

syncAttempt

服务器在最终拒绝请求之前尝试同步数据的次数。

data

如果配置的冲突处理程序为 Automerge,则将填充此字段以显示 Automerge 为每个字段做出的决策。提供的操作可以是:

  • REJECTED - Automerge 拒绝传入的字段值,而是使用服务器中的值。

  • ADDED - 由于服务器中没有预先存在的值,因此 Automerge 添加传入字段。

  • APPENDED - Automerge 将传入值追加到存在于服务器中的列表的值。

  • MERGED - Automerge 将传入值合并到服务器中存在的集的值。

日志类型参考

RequestSummary

  • requestId:请求的唯一标识符。

  • graphQLAPIId:发出请求的 GraphQL API 的 ID。

  • statusCode:HTTP 状态代码响应。

  • latency:请求的端到端延迟,以纳秒为单位,整数值。

{ "logType": "RequestSummary", "requestId": "dbe87af3-c114-4b32-ae79-8af11f3f96f1", "graphQLAPIId": "pmo28inf75eepg63qxq4ekoeg4", "statusCode": 200, "latency": 242000000 }

ExecutionSummary

  • requestId:请求的唯一标识符。

  • graphQLAPIId:发出请求的 GraphQL API 的 ID。

  • startTime:请求的 GraphQL 执行的开始时间戳,采用 RFC 3339 格式。

  • endTime:请求的 GraphQL 执行的结束时间戳,采用 RFC 3339 格式。

  • duration:经过的总 GraphQL 执行时间,以纳秒为单位,整数值。

  • version:ExecutionSummary 的架构版本。

  • parsing:
    • startOffset:解析的开始偏移,以纳秒为单位,与执行开始相对,整数值。

    • duration:解析所花费的时间,以纳秒为单位,整数值。

  • validation:
    • startOffset:验证的开始偏移,以纳秒为单位,与执行开始相对,整数值。

    • duration:执行验证所花费的时间,以纳秒为单位,整数值。

{ "duration": 217406145, "logType": "ExecutionSummary", "requestId": "dbe87af3-c114-4b32-ae79-8af11f3f96f1", "startTime": "2019-01-01T06:06:18.956Z", "endTime": "2019-01-01T06:06:19.174Z", "parsing": { "startOffset": 49033, "duration": 34784 }, "version": 1, "validation": { "startOffset": 129048, "duration": 69126 }, "graphQLAPIId": "pmo28inf75eepg63qxq4ekoeg4" }

跟踪

  • requestId:请求的唯一标识符。

  • graphQLAPIId:发出请求的 GraphQL API 的 ID。

  • startOffset:字段解析的开始偏移,以纳秒为单位,与执行开始相对,整数值。

  • duration:解析字段所花费的时间,以纳秒为单位,整数值。

  • fieldName:所解析字段的名称。

  • parentType:所解析字段的父类型。

  • returnType:所解析字段的返回类型。

  • path:路径分段列表,从响应的根开始,以所解析字段结束。

  • resolverArn:用于字段解析的解析程序的 ARN。可能不会出现在嵌套字段中。

{ "duration": 216820346, "logType": "Tracing", "path": [ "putItem" ], "fieldName": "putItem", "startOffset": 178156, "resolverArn": "arn:aws:appsync:us-east-1:111111111111:apis/pmo28inf75eepg63qxq4ekoeg4/types/Mutation/fields/putItem", "requestId": "dbe87af3-c114-4b32-ae79-8af11f3f96f1", "parentType": "Mutation", "returnType": "Item", "graphQLAPIId": "pmo28inf75eepg63qxq4ekoeg4" }

使用 Amazon CloudWatch Logs Insights 分析您的日志

以下是您可以运行的查询示例,以获取有关 GraphQL 操作的性能和运行状况的可行的见解。这些示例可作为 CloudWatch Logs Insights 控制台中的示例查询提供。在 Amazon CloudWatch 控制台中,选择 Logs Insights,选择 GraphQL API 的 AWS AppSync 日志组,然后在 Sample queries (示例查询) 下选择 AWS AppSync queries (AWS AppSync 查询)

以下查询返回具有最大延迟的前 10 个 GraphQL 请求:

fields requestId, latency | filter logType = "RequestSummary" | limit 10 | sort latency desc

以下查询返回具有最大延迟的前 10 个解析程序:

fields resolverArn, duration | filter logType = "Tracing" | limit 10 | sort duration desc

以下查询返回最常调用的解析程序:

fields ispresent(resolverArn) as isRes | stats count() as invocationCount by resolverArn | filter isRes and logType = "Tracing" | limit 10 | sort invocationCount desc

以下查询返回映射模板中具有最多错误的解析程序:

fields ispresent(resolverArn) as isRes | stats count() as errorCount by resolverArn, logType | filter isRes and (logType = "RequestMapping" or logType = "ResponseMapping") and fieldInError | limit 10 | sort errorCount desc

以下查询返回解析程序延迟统计数据:

fields ispresent(resolverArn) as isRes | stats min(duration), max(duration), avg(duration) as avg_dur by resolverArn | filter isRes and logType = "Tracing" | limit 10 | sort avg_dur desc

以下查询返回字段延迟统计数据:

stats min(duration), max(duration), avg(duration) as avg_dur by concat(parentType, '/', fieldName) as fieldKey | filter logType = "Tracing" | limit 10 | sort avg_dur desc

CloudWatch Logs Insights 查询的结果可以导出到 CloudWatch 控制面板。

使用 Amazon Elasticsearch Service 分析您的日志

您可以使用 Amazon Elasticsearch Service 搜索、分析和可视化您的 AWS AppSync 日志,以确定性能瓶颈和操作问题的根本原因。您可以识别具有最大延迟和最多错误的解析程序。此外,您可以使用 Kibana 创建具有强大可视化效果的仪表板。Kibana 是 Amazon ES 中提供的开源数据可视化和挖掘工具。使用 Kibana 控制面板,您可以持续监控 GraphQL 操作的性能和运行状况。例如,您可以创建控制面板,使您能够可视化 GraphQL 请求的 P90 延迟,并深入了解每个解析程序的 P90 延迟。

当使用 Amazon ES 时,请使用“cwl*”作为筛选器模式来搜索 Elasticsearch 索引。Elasticsearch 将为从 CloudWatch Logs 流式传输而来的日志编制索引,前缀为“cwl-”。要将 AWS AppSync API 日志与发送到 Elasticsearch 的其他 CloudWatch logs 日志区分开来,建议您在搜索中添加 graphQLAPIID.keyword=<AWS AppSync's GraphQL API Id> 的其他筛选表达式。

日志格式迁移

AWS AppSync 在 2019 年 5 月 8 日或之后生成的日志事件的格式为完全结构化的 JSON。如果要在 2019 年 5 月 8 日之前分析 GraphQL 请求,可以使用 GitHub 示例中提供的脚本将以前的日志迁移到完全结构化的 JSON。如果需要在 2019 年 5 月 8 日之前使用日志格式,请使用以下设置创建支持服务单:将 Type (类型) 设置为 Account Management (账户管理),然后将 Category (类别) 设置为 General Account Question (一般账户问题)

您也可以选择在 中启用指标筛选条件CloudWatch。然后,您可以使用这些指标筛选条件将日志数据转换为 CloudWatch 数值指标,以便对它们生成图表或设置警报。