AWS AppSync
AWS AppSync Developer Guide

Monitoring and Logging

Monitoring with Amazon CloudWatch

You monitor and debug requests in AWS AppSync by using Amazon CloudWatch. Using AWS AppSync, you can use GraphQL to request data from the cloud. There are often times when you want to get more information about the execution of your API. To help debug issues related to request execution of your GraphQL API, you can enable Amazon CloudWatch Logs to monitor API calls. Once enabled, AWS AppSync logs API calls in CloudWatch.

Setup and Configuration

You can enable logging on a GraphQL API automatically through the AWS AppSync console.

  1. Sign in to the AWS AppSync console.

  2. Choose Settings from the navigation panel.

  3. Under Logging, click the toggle to Enable Logs.

  4. When the console prompts you, provide or create a CloudWatch ARN role.

  5. (Optional) Choose to configure the Field resolver log level from the list.

  6. Choose Save. The logging is automatically configured for your API.

Manual Role Configuration

To enable CloudWatch Logs, you must grant AWS AppSync correct permissions to write logs to CloudWatch for your account. To do this, you need to provide a service role ARN so that AWS AppSync can assume this role when writing the logs.

First, navigate to the IAM console. Then create a new policy with the name AWSAppSyncPushToCloudWatchLogsPolicy that has the following definition:

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

Next, create a new role with the name AWSAppSyncPushToCloudWatchLogsRole, and attach the above policy to this role. Edit the trust relationship for this role to have the following:

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

Copy the role ARN and register this with AWS AppSync to enable writing into CloudWatch.

CloudWatch Metrics

You can use CloudWatch metrics to monitor and provide alerts about specific events that can be triggered by HTTP status codes or by latency, such as the overall GraphQL request and response latency. The following are the metrics that are emitted.

4XX The number of errors captured as a result of invalid requests due to incorrect client configuration. Typically, these errors happen anywhere outside of the GraphQL execution. For example, this could be an incorrect JSON payload or an incorrect query in the request, when the service is throttled, or even a potential misconfiguration on the Auth settings.

Unit: Count. Use the Sum statistic to get the total occurrences of these errors.

5XX Errors encountered during the execution of a GraphQL query. For example, this could occur when a query request is initiated for an empty or incorrect schema, if the Amazon Cognito user pool ID or AWS Region is invalid. Alternatively, this could also happen if AWS AppSync encounters an issue during an execution of a request.

Unit: Count. Use the Sum statistic to get the total occurrences of these errors.

Latency The time between when AWS AppSync receives a request from a client and when it returns a response to the client. This doesn't include the network latency encountered for a response to reach the end devices.

Unit: Millisecond. Use the Average statistic to evaluate expected latencies.

CloudWatch Logs

You can configure two types of logging on any new or existing GraphQL API: request-level and field-level.

Request-Level Logs

When enabled, the following information is logged:

  • The request and response HTTP headers

  • The GraphQL query that is being executed in the request

  • The overall execution summary

  • New and existing GraphQL subscriptions that are registered

Field-Level Logs

When enabled, the following information is logged:

  • Generated Request Mapping with source and arguments for each field

  • The transformed Response Mapping for each field, which includes the data as a result of resolving that field

  • Tracing information for each field

If you turn on logging, AWS AppSync manages the CloudWatch Logs. The process includes creating log groups and log streams, and reporting to the log streams with these logs.

When you enable logging on a GraphQL API and make requests, AWS AppSync creates a log group and log streams under the log group. The log group is named following the /aws/appsync/apis/{graphql_api_id} format. Within each log group, the logs are further divided into log streams. These are ordered by Last Event Time as logged data is reported.

Every log event is tagged with the x-amzn-RequestId of that request. This helps you filter log events in CloudWatch to get all logged information pertaining to that request. You can get the RequestId from the response headers of every GraphQL AWS AppSync request.

The field-Level logging is configured with the following log levels:

  • NONE - No field-level logs are captured.

  • ERROR - Logs the following information only for the fields that are in error:
    • The error section in the server response

    • Field-level errors

    • The generated request/response functions that got resolved for error fields

  • ALL - The following information is logged for all fields in the query:
    • Field-level tracing information

    • The generated request/response functions that got resolved for each field

Benefits of Enabling Monitoring

You can use logging and metrics to identify, troubleshoot, and optimize your GraphQL queries. For example, these will help you debug latency issues using the tracing information that is logged for each field in the query. To demonstrate this, suppose you are using one or more resolvers nested in a GraphQL query. A sample field execution in CloudWatch Logs might look similar to the following:

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

This might correspond to a GraphQL schema, similar to the following:

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

In the log results above, path shows a single item in your data returned from running a query named singlePost(). In this example, it's representing the name field at the first index (0). startOffset gives an offset from the start of the GraphQL query execution. duration is the total time to resolve the field. These values can be useful to troubleshoot why data from a particular data source might be running slower than expected, or if a specific field is slowing down the entire query. For example, you might choose to increase provisioned throughput for an Amazon DynamoDB table, or remove a specific field from a query that is causing the overall execution to perform poorly.

You can also choose to enable metric filters in CloudWatch. You can then use these metric filters to turn log data into numerical CloudWatch metrics, so you can graph or set an alarm on them.