From b5a55f73700a4c44d94ffc3ceca8ca6a7a6f71b3 Mon Sep 17 00:00:00 2001 From: maz Date: Thu, 5 Sep 2024 09:35:02 +0900 Subject: [PATCH] feat: support INFO and DEBUG logging levels for AppSync GraphQL APIs --- ...efaultTestDeployAssert06C4E034.assets.json | 19 + ...aultTestDeployAssert06C4E034.template.json | 36 ++ .../index.js | 1 + ...ppsync-graphql-field-level-log.assets.json | 32 ++ ...sync-graphql-field-level-log.template.json | 347 +++++++++++++++ .../cdk.out | 1 + .../integ.json | 12 + .../manifest.json | 161 +++++++ .../tree.json | 408 ++++++++++++++++++ .../test/integ.graphql-field-level-log.ts | 19 + packages/aws-cdk-lib/aws-appsync/README.md | 5 + .../aws-cdk-lib/aws-appsync/lib/graphqlapi.ts | 14 +- .../aws-appsync/test/appsync.test.ts | 26 +- 13 files changed, 1077 insertions(+), 4 deletions(-) create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-field-level-log.js.snapshot/GraphQLFieldLevelLogDefaultTestDeployAssert06C4E034.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-field-level-log.js.snapshot/GraphQLFieldLevelLogDefaultTestDeployAssert06C4E034.template.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-field-level-log.js.snapshot/asset.e4afb15788ec44ed9ff3377e1d131ba2768d7b2e2931bc000d1f2005879b3035/index.js create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-field-level-log.js.snapshot/aws-cdk-appsync-graphql-field-level-log.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-field-level-log.js.snapshot/aws-cdk-appsync-graphql-field-level-log.template.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-field-level-log.js.snapshot/cdk.out create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-field-level-log.js.snapshot/integ.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-field-level-log.js.snapshot/manifest.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-field-level-log.js.snapshot/tree.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-field-level-log.ts diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-field-level-log.js.snapshot/GraphQLFieldLevelLogDefaultTestDeployAssert06C4E034.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-field-level-log.js.snapshot/GraphQLFieldLevelLogDefaultTestDeployAssert06C4E034.assets.json new file mode 100644 index 0000000000000..5488e46f889eb --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-field-level-log.js.snapshot/GraphQLFieldLevelLogDefaultTestDeployAssert06C4E034.assets.json @@ -0,0 +1,19 @@ +{ + "version": "36.0.5", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "GraphQLFieldLevelLogDefaultTestDeployAssert06C4E034.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-field-level-log.js.snapshot/GraphQLFieldLevelLogDefaultTestDeployAssert06C4E034.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-field-level-log.js.snapshot/GraphQLFieldLevelLogDefaultTestDeployAssert06C4E034.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-field-level-log.js.snapshot/GraphQLFieldLevelLogDefaultTestDeployAssert06C4E034.template.json @@ -0,0 +1,36 @@ +{ + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-field-level-log.js.snapshot/asset.e4afb15788ec44ed9ff3377e1d131ba2768d7b2e2931bc000d1f2005879b3035/index.js b/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-field-level-log.js.snapshot/asset.e4afb15788ec44ed9ff3377e1d131ba2768d7b2e2931bc000d1f2005879b3035/index.js new file mode 100644 index 0000000000000..ae6165a46ea1e --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-field-level-log.js.snapshot/asset.e4afb15788ec44ed9ff3377e1d131ba2768d7b2e2931bc000d1f2005879b3035/index.js @@ -0,0 +1 @@ +"use strict";var h=Object.create;var d=Object.defineProperty;var w=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var C=Object.getPrototypeOf,P=Object.prototype.hasOwnProperty;var b=(e,o)=>{for(var n in o)d(e,n,{get:o[n],enumerable:!0})},p=(e,o,n,t)=>{if(o&&typeof o=="object"||typeof o=="function")for(let r of f(o))!P.call(e,r)&&r!==n&&d(e,r,{get:()=>o[r],enumerable:!(t=w(o,r))||t.enumerable});return e};var S=(e,o,n)=>(n=e!=null?h(C(e)):{},p(o||!e||!e.__esModule?d(n,"default",{value:e,enumerable:!0}):n,e)),G=e=>p(d({},"__esModule",{value:!0}),e);var q={};b(q,{handler:()=>E});module.exports=G(q);var i=S(require("@aws-sdk/client-cloudwatch-logs"));async function R(e,o,n){await n(async()=>{try{let t={logGroupName:e},r=new i.CreateLogGroupCommand(t);await o.send(r)}catch(t){if(t.name==="ResourceAlreadyExistsException")return;throw t}})}async function x(e,o,n){await n(async()=>{try{let t={logGroupName:e},r=new i.DeleteLogGroupCommand(t);await o.send(r)}catch(t){if(t.name==="ResourceNotFoundException")return;throw t}})}async function y(e,o,n,t){await n(async()=>{if(t){let r={logGroupName:e,retentionInDays:t},s=new i.PutRetentionPolicyCommand(r);await o.send(s)}else{let r={logGroupName:e},s=new i.DeleteRetentionPolicyCommand(r);await o.send(s)}})}async function E(e,o){try{console.log(JSON.stringify({...e,ResponseURL:"..."}));let t=e.ResourceProperties.LogGroupName,r=e.ResourceProperties.LogGroupRegion,s=L(e.ResourceProperties.SdkRetry?.maxRetries)??5,a=I(s),m={logger:console,region:r,maxAttempts:Math.max(5,s)},c=new i.CloudWatchLogsClient(m);if((e.RequestType==="Create"||e.RequestType==="Update")&&(await R(t,c,a),await y(t,c,a,L(e.ResourceProperties.RetentionInDays)),e.RequestType==="Create")){let g=new i.CloudWatchLogsClient({logger:console,region:process.env.AWS_REGION});await R(`/aws/lambda/${o.functionName}`,g,a),await y(`/aws/lambda/${o.functionName}`,g,a,1)}e.RequestType==="Delete"&&e.ResourceProperties.RemovalPolicy==="destroy"&&await x(t,c,a),await n("SUCCESS","OK",t)}catch(t){console.log(t),await n("FAILED",t.message,e.ResourceProperties.LogGroupName)}function n(t,r,s){let a=JSON.stringify({Status:t,Reason:r,PhysicalResourceId:s,StackId:e.StackId,RequestId:e.RequestId,LogicalResourceId:e.LogicalResourceId,Data:{LogGroupName:e.ResourceProperties.LogGroupName}});console.log("Responding",a);let m=require("url").parse(e.ResponseURL),c={hostname:m.hostname,path:m.path,method:"PUT",headers:{"content-type":"","content-length":Buffer.byteLength(a,"utf8")}};return new Promise((g,l)=>{try{let u=require("https").request(c,g);u.on("error",l),u.write(a),u.end()}catch(u){l(u)}})}}function L(e,o=10){if(e!==void 0)return parseInt(e,o)}function I(e,o=100,n=10*1e3){return async t=>{let r=0;do try{return await t()}catch(s){if(s.name==="OperationAbortedException"||s.name==="ThrottlingException")if(rsetTimeout(a,k(r,o,n)));continue}else throw new Error("Out of attempts to change log group");throw s}while(!0)}}function k(e,o,n){return Math.round(Math.random()*Math.min(n,o*2**e))}0&&(module.exports={handler}); diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-field-level-log.js.snapshot/aws-cdk-appsync-graphql-field-level-log.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-field-level-log.js.snapshot/aws-cdk-appsync-graphql-field-level-log.assets.json new file mode 100644 index 0000000000000..a046dbac9c594 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-field-level-log.js.snapshot/aws-cdk-appsync-graphql-field-level-log.assets.json @@ -0,0 +1,32 @@ +{ + "version": "36.0.5", + "files": { + "e4afb15788ec44ed9ff3377e1d131ba2768d7b2e2931bc000d1f2005879b3035": { + "source": { + "path": "asset.e4afb15788ec44ed9ff3377e1d131ba2768d7b2e2931bc000d1f2005879b3035", + "packaging": "zip" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "e4afb15788ec44ed9ff3377e1d131ba2768d7b2e2931bc000d1f2005879b3035.zip", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + }, + "57fb978b024ca21f315c2ab7a4d2c94dc91e01b0976bbdaaef87d312c7fabd6b": { + "source": { + "path": "aws-cdk-appsync-graphql-field-level-log.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "57fb978b024ca21f315c2ab7a4d2c94dc91e01b0976bbdaaef87d312c7fabd6b.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-field-level-log.js.snapshot/aws-cdk-appsync-graphql-field-level-log.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-field-level-log.js.snapshot/aws-cdk-appsync-graphql-field-level-log.template.json new file mode 100644 index 0000000000000..20ad84d2c90b0 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-field-level-log.js.snapshot/aws-cdk-appsync-graphql-field-level-log.template.json @@ -0,0 +1,347 @@ +{ + "Resources": { + "LambdaAPIApiLogsRole4F7D908F": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "appsync.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSAppSyncPushToCloudWatchLogs" + ] + ] + } + ] + } + }, + "LambdaAPID6A5A92B": { + "Type": "AWS::AppSync::GraphQLApi", + "Properties": { + "AuthenticationType": "API_KEY", + "LogConfig": { + "CloudWatchLogsRoleArn": { + "Fn::GetAtt": [ + "LambdaAPIApiLogsRole4F7D908F", + "Arn" + ] + }, + "FieldLogLevel": "INFO" + }, + "Name": "LambdaAPI" + } + }, + "LambdaAPISchemaCC5CA3D2": { + "Type": "AWS::AppSync::GraphQLSchema", + "Properties": { + "ApiId": { + "Fn::GetAtt": [ + "LambdaAPID6A5A92B", + "ApiId" + ] + }, + "Definition": "schema {\n query: Query\n mutation: Mutation\n}\n\ntype Query {\n getPost(id:ID!): Post\n allPosts: [Post]\n}\n\ntype Mutation {\n addPost(id: ID!, author: String!, title: String, content: String, url: String): Post!\n}\n\ntype Post {\n id: ID!\n author: String!\n title: String\n content: String\n url: String\n ups: Int\n downs: Int\n relatedPosts: [Post]\n relatedPostsMaxBatchSize: [Post]\n}" + } + }, + "LambdaAPIDefaultApiKey15F6897D": { + "Type": "AWS::AppSync::ApiKey", + "Properties": { + "ApiId": { + "Fn::GetAtt": [ + "LambdaAPID6A5A92B", + "ApiId" + ] + } + }, + "DependsOn": [ + "LambdaAPISchemaCC5CA3D2" + ] + }, + "LambdaAPILogRetention217BE0A6": { + "Type": "Custom::LogRetention", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8aFD4BFC8A", + "Arn" + ] + }, + "LogGroupName": { + "Fn::Join": [ + "", + [ + "/aws/appsync/apis/", + { + "Fn::GetAtt": [ + "LambdaAPID6A5A92B", + "ApiId" + ] + } + ] + ] + } + } + }, + "LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8aServiceRole9741ECFB": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8aServiceRoleDefaultPolicyADDA7DEB": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "logs:DeleteRetentionPolicy", + "logs:PutRetentionPolicy" + ], + "Effect": "Allow", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8aServiceRoleDefaultPolicyADDA7DEB", + "Roles": [ + { + "Ref": "LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8aServiceRole9741ECFB" + } + ] + } + }, + "LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8aFD4BFC8A": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Handler": "index.handler", + "Runtime": { + "Fn::FindInMap": [ + "LatestNodeRuntimeMap", + { + "Ref": "AWS::Region" + }, + "value" + ] + }, + "Timeout": 900, + "Code": { + "S3Bucket": { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "S3Key": "e4afb15788ec44ed9ff3377e1d131ba2768d7b2e2931bc000d1f2005879b3035.zip" + }, + "Role": { + "Fn::GetAtt": [ + "LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8aServiceRole9741ECFB", + "Arn" + ] + } + }, + "DependsOn": [ + "LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8aServiceRoleDefaultPolicyADDA7DEB", + "LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8aServiceRole9741ECFB" + ] + } + }, + "Mappings": { + "LatestNodeRuntimeMap": { + "af-south-1": { + "value": "nodejs20.x" + }, + "ap-east-1": { + "value": "nodejs20.x" + }, + "ap-northeast-1": { + "value": "nodejs20.x" + }, + "ap-northeast-2": { + "value": "nodejs20.x" + }, + "ap-northeast-3": { + "value": "nodejs20.x" + }, + "ap-south-1": { + "value": "nodejs20.x" + }, + "ap-south-2": { + "value": "nodejs20.x" + }, + "ap-southeast-1": { + "value": "nodejs20.x" + }, + "ap-southeast-2": { + "value": "nodejs20.x" + }, + "ap-southeast-3": { + "value": "nodejs20.x" + }, + "ap-southeast-4": { + "value": "nodejs20.x" + }, + "ap-southeast-5": { + "value": "nodejs20.x" + }, + "ap-southeast-7": { + "value": "nodejs20.x" + }, + "ca-central-1": { + "value": "nodejs20.x" + }, + "ca-west-1": { + "value": "nodejs20.x" + }, + "cn-north-1": { + "value": "nodejs18.x" + }, + "cn-northwest-1": { + "value": "nodejs18.x" + }, + "eu-central-1": { + "value": "nodejs20.x" + }, + "eu-central-2": { + "value": "nodejs20.x" + }, + "eu-isoe-west-1": { + "value": "nodejs18.x" + }, + "eu-north-1": { + "value": "nodejs20.x" + }, + "eu-south-1": { + "value": "nodejs20.x" + }, + "eu-south-2": { + "value": "nodejs20.x" + }, + "eu-west-1": { + "value": "nodejs20.x" + }, + "eu-west-2": { + "value": "nodejs20.x" + }, + "eu-west-3": { + "value": "nodejs20.x" + }, + "il-central-1": { + "value": "nodejs20.x" + }, + "me-central-1": { + "value": "nodejs20.x" + }, + "me-south-1": { + "value": "nodejs20.x" + }, + "mx-central-1": { + "value": "nodejs20.x" + }, + "sa-east-1": { + "value": "nodejs20.x" + }, + "us-east-1": { + "value": "nodejs20.x" + }, + "us-east-2": { + "value": "nodejs20.x" + }, + "us-gov-east-1": { + "value": "nodejs18.x" + }, + "us-gov-west-1": { + "value": "nodejs18.x" + }, + "us-iso-east-1": { + "value": "nodejs18.x" + }, + "us-iso-west-1": { + "value": "nodejs18.x" + }, + "us-isob-east-1": { + "value": "nodejs18.x" + }, + "us-west-1": { + "value": "nodejs20.x" + }, + "us-west-2": { + "value": "nodejs20.x" + } + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-field-level-log.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-field-level-log.js.snapshot/cdk.out new file mode 100644 index 0000000000000..bd5311dc372de --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-field-level-log.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"36.0.5"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-field-level-log.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-field-level-log.js.snapshot/integ.json new file mode 100644 index 0000000000000..4442ce0691a5c --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-field-level-log.js.snapshot/integ.json @@ -0,0 +1,12 @@ +{ + "version": "36.0.5", + "testCases": { + "GraphQLFieldLevelLog/DefaultTest": { + "stacks": [ + "aws-cdk-appsync-graphql-field-level-log" + ], + "assertionStack": "GraphQLFieldLevelLog/DefaultTest/DeployAssert", + "assertionStackName": "GraphQLFieldLevelLogDefaultTestDeployAssert06C4E034" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-field-level-log.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-field-level-log.js.snapshot/manifest.json new file mode 100644 index 0000000000000..f213619663d70 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-field-level-log.js.snapshot/manifest.json @@ -0,0 +1,161 @@ +{ + "version": "36.0.5", + "artifacts": { + "aws-cdk-appsync-graphql-field-level-log.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "aws-cdk-appsync-graphql-field-level-log.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "aws-cdk-appsync-graphql-field-level-log": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "aws-cdk-appsync-graphql-field-level-log.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/57fb978b024ca21f315c2ab7a4d2c94dc91e01b0976bbdaaef87d312c7fabd6b.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "aws-cdk-appsync-graphql-field-level-log.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "aws-cdk-appsync-graphql-field-level-log.assets" + ], + "metadata": { + "/aws-cdk-appsync-graphql-field-level-log/LambdaAPI/ApiLogsRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "LambdaAPIApiLogsRole4F7D908F" + } + ], + "/aws-cdk-appsync-graphql-field-level-log/LambdaAPI/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "LambdaAPID6A5A92B" + } + ], + "/aws-cdk-appsync-graphql-field-level-log/LambdaAPI/Schema": [ + { + "type": "aws:cdk:logicalId", + "data": "LambdaAPISchemaCC5CA3D2" + } + ], + "/aws-cdk-appsync-graphql-field-level-log/LambdaAPI/DefaultApiKey": [ + { + "type": "aws:cdk:logicalId", + "data": "LambdaAPIDefaultApiKey15F6897D" + } + ], + "/aws-cdk-appsync-graphql-field-level-log/LambdaAPI/LogRetention/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "LambdaAPILogRetention217BE0A6" + } + ], + "/aws-cdk-appsync-graphql-field-level-log/LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8a/ServiceRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8aServiceRole9741ECFB" + } + ], + "/aws-cdk-appsync-graphql-field-level-log/LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8a/ServiceRole/DefaultPolicy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8aServiceRoleDefaultPolicyADDA7DEB" + } + ], + "/aws-cdk-appsync-graphql-field-level-log/LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8a/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8aFD4BFC8A" + } + ], + "/aws-cdk-appsync-graphql-field-level-log/LatestNodeRuntimeMap": [ + { + "type": "aws:cdk:logicalId", + "data": "LatestNodeRuntimeMap" + } + ], + "/aws-cdk-appsync-graphql-field-level-log/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/aws-cdk-appsync-graphql-field-level-log/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "aws-cdk-appsync-graphql-field-level-log" + }, + "GraphQLFieldLevelLogDefaultTestDeployAssert06C4E034.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "GraphQLFieldLevelLogDefaultTestDeployAssert06C4E034.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "GraphQLFieldLevelLogDefaultTestDeployAssert06C4E034": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "GraphQLFieldLevelLogDefaultTestDeployAssert06C4E034.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "GraphQLFieldLevelLogDefaultTestDeployAssert06C4E034.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "GraphQLFieldLevelLogDefaultTestDeployAssert06C4E034.assets" + ], + "metadata": { + "/GraphQLFieldLevelLog/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/GraphQLFieldLevelLog/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "GraphQLFieldLevelLog/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-field-level-log.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-field-level-log.js.snapshot/tree.json new file mode 100644 index 0000000000000..87579bbdf63c1 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-field-level-log.js.snapshot/tree.json @@ -0,0 +1,408 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "aws-cdk-appsync-graphql-field-level-log": { + "id": "aws-cdk-appsync-graphql-field-level-log", + "path": "aws-cdk-appsync-graphql-field-level-log", + "children": { + "LambdaAPI": { + "id": "LambdaAPI", + "path": "aws-cdk-appsync-graphql-field-level-log/LambdaAPI", + "children": { + "ApiLogsRole": { + "id": "ApiLogsRole", + "path": "aws-cdk-appsync-graphql-field-level-log/LambdaAPI/ApiLogsRole", + "children": { + "ImportApiLogsRole": { + "id": "ImportApiLogsRole", + "path": "aws-cdk-appsync-graphql-field-level-log/LambdaAPI/ApiLogsRole/ImportApiLogsRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-cdk-appsync-graphql-field-level-log/LambdaAPI/ApiLogsRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "appsync.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "managedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSAppSyncPushToCloudWatchLogs" + ] + ] + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnRole", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-cdk-appsync-graphql-field-level-log/LambdaAPI/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::AppSync::GraphQLApi", + "aws:cdk:cloudformation:props": { + "authenticationType": "API_KEY", + "logConfig": { + "cloudWatchLogsRoleArn": { + "Fn::GetAtt": [ + "LambdaAPIApiLogsRole4F7D908F", + "Arn" + ] + }, + "fieldLogLevel": "INFO" + }, + "name": "LambdaAPI" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_appsync.CfnGraphQLApi", + "version": "0.0.0" + } + }, + "Schema": { + "id": "Schema", + "path": "aws-cdk-appsync-graphql-field-level-log/LambdaAPI/Schema", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::AppSync::GraphQLSchema", + "aws:cdk:cloudformation:props": { + "apiId": { + "Fn::GetAtt": [ + "LambdaAPID6A5A92B", + "ApiId" + ] + }, + "definition": "schema {\n query: Query\n mutation: Mutation\n}\n\ntype Query {\n getPost(id:ID!): Post\n allPosts: [Post]\n}\n\ntype Mutation {\n addPost(id: ID!, author: String!, title: String, content: String, url: String): Post!\n}\n\ntype Post {\n id: ID!\n author: String!\n title: String\n content: String\n url: String\n ups: Int\n downs: Int\n relatedPosts: [Post]\n relatedPostsMaxBatchSize: [Post]\n}" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_appsync.CfnGraphQLSchema", + "version": "0.0.0" + } + }, + "DefaultApiKey": { + "id": "DefaultApiKey", + "path": "aws-cdk-appsync-graphql-field-level-log/LambdaAPI/DefaultApiKey", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::AppSync::ApiKey", + "aws:cdk:cloudformation:props": { + "apiId": { + "Fn::GetAtt": [ + "LambdaAPID6A5A92B", + "ApiId" + ] + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_appsync.CfnApiKey", + "version": "0.0.0" + } + }, + "LogRetention": { + "id": "LogRetention", + "path": "aws-cdk-appsync-graphql-field-level-log/LambdaAPI/LogRetention", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-appsync-graphql-field-level-log/LambdaAPI/LogRetention/Resource", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnResource", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_logs.LogRetention", + "version": "0.0.0" + } + }, + "LogGroup": { + "id": "LogGroup", + "path": "aws-cdk-appsync-graphql-field-level-log/LambdaAPI/LogGroup", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_appsync.GraphqlApi", + "version": "0.0.0" + } + }, + "LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8a": { + "id": "LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8a", + "path": "aws-cdk-appsync-graphql-field-level-log/LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8a", + "children": { + "Code": { + "id": "Code", + "path": "aws-cdk-appsync-graphql-field-level-log/LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8a/Code", + "children": { + "Stage": { + "id": "Stage", + "path": "aws-cdk-appsync-graphql-field-level-log/LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8a/Code/Stage", + "constructInfo": { + "fqn": "aws-cdk-lib.AssetStaging", + "version": "0.0.0" + } + }, + "AssetBucket": { + "id": "AssetBucket", + "path": "aws-cdk-appsync-graphql-field-level-log/LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8a/Code/AssetBucket", + "constructInfo": { + "fqn": "aws-cdk-lib.aws_s3.BucketBase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_s3_assets.Asset", + "version": "0.0.0" + } + }, + "ServiceRole": { + "id": "ServiceRole", + "path": "aws-cdk-appsync-graphql-field-level-log/LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8a/ServiceRole", + "children": { + "ImportServiceRole": { + "id": "ImportServiceRole", + "path": "aws-cdk-appsync-graphql-field-level-log/LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8a/ServiceRole/ImportServiceRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-cdk-appsync-graphql-field-level-log/LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8a/ServiceRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "managedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnRole", + "version": "0.0.0" + } + }, + "DefaultPolicy": { + "id": "DefaultPolicy", + "path": "aws-cdk-appsync-graphql-field-level-log/LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8a/ServiceRole/DefaultPolicy", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-appsync-graphql-field-level-log/LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8a/ServiceRole/DefaultPolicy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Policy", + "aws:cdk:cloudformation:props": { + "policyDocument": { + "Statement": [ + { + "Action": [ + "logs:DeleteRetentionPolicy", + "logs:PutRetentionPolicy" + ], + "Effect": "Allow", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "policyName": "LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8aServiceRoleDefaultPolicyADDA7DEB", + "roles": [ + { + "Ref": "LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8aServiceRole9741ECFB" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Policy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-cdk-appsync-graphql-field-level-log/LogRetentionaae0aa3c5b4d4f87b02d85b201efdd8a/Resource", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnResource", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "LatestNodeRuntimeMap": { + "id": "LatestNodeRuntimeMap", + "path": "aws-cdk-appsync-graphql-field-level-log/LatestNodeRuntimeMap", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnMapping", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "aws-cdk-appsync-graphql-field-level-log/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "aws-cdk-appsync-graphql-field-level-log/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + }, + "GraphQLFieldLevelLog": { + "id": "GraphQLFieldLevelLog", + "path": "GraphQLFieldLevelLog", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "GraphQLFieldLevelLog/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "GraphQLFieldLevelLog/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "GraphQLFieldLevelLog/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "GraphQLFieldLevelLog/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "GraphQLFieldLevelLog/DefaultTest/DeployAssert/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTestCase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTest", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.App", + "version": "0.0.0" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-field-level-log.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-field-level-log.ts new file mode 100644 index 0000000000000..01d94044c3e67 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-appsync/test/integ.graphql-field-level-log.ts @@ -0,0 +1,19 @@ +import * as path from 'path'; +import * as cdk from 'aws-cdk-lib'; +import { IntegTest } from '@aws-cdk/integ-tests-alpha'; +import * as appsync from 'aws-cdk-lib/aws-appsync'; + +const app = new cdk.App(); +const stack = new cdk.Stack(app, 'aws-cdk-appsync-graphql-field-level-log'); + +new appsync.GraphqlApi(stack, 'LambdaAPI', { + name: 'LambdaAPI', + schema: appsync.SchemaFile.fromAsset(path.join(__dirname, 'appsync.lambda.graphql')), + logConfig: { + fieldLogLevel: appsync.FieldLogLevel.INFO, + } +}); + +new IntegTest(app, 'GraphQLFieldLevelLog', { + testCases: [stack], +}); diff --git a/packages/aws-cdk-lib/aws-appsync/README.md b/packages/aws-cdk-lib/aws-appsync/README.md index 675d10dadbfc2..3bbe919dabc2f 100644 --- a/packages/aws-cdk-lib/aws-appsync/README.md +++ b/packages/aws-cdk-lib/aws-appsync/README.md @@ -547,6 +547,10 @@ log data set to never expire. If you want to set a different expiration period, To obtain the GraphQL API's log group as a `logs.ILogGroup` use the `logGroup` property of the `GraphqlApi` construct. +Also you can choose the log level by setting the `fieldLogLevel` property. + +For more infomertion, see [CloudWatch logs](https://docs.aws.amazon.com/en_us/appsync/latest/devguide/monitoring.html#cwl). + ```ts import * as logs from 'aws-cdk-lib/aws-logs'; @@ -559,6 +563,7 @@ new appsync.GraphqlApi(this, 'api', { name: 'myApi', definition: appsync.Definition.fromFile(path.join(__dirname, 'myApi.graphql')), logConfig, + fieldLogLevel: appsync.FieldLogLevel.INFO, }); ``` diff --git a/packages/aws-cdk-lib/aws-appsync/lib/graphqlapi.ts b/packages/aws-cdk-lib/aws-appsync/lib/graphqlapi.ts index 4332257d5484c..9bf1bd3b1a8e9 100644 --- a/packages/aws-cdk-lib/aws-appsync/lib/graphqlapi.ts +++ b/packages/aws-cdk-lib/aws-appsync/lib/graphqlapi.ts @@ -186,15 +186,23 @@ export interface AuthorizationConfig { */ export enum FieldLogLevel { /** - * No logging + * Resolver logging is disabled */ NONE = 'NONE', /** - * Error logging + * Only Error messages appear in logs */ ERROR = 'ERROR', /** - * All logging + * Info and Error messages appear in logs + */ + INFO = 'INFO', + /** + * Debug, Info, and Error messages, appear in logs + */ + DEBUG = 'DEBUG', + /** + * All messages (Debug, Error, Info, and Trace) appear in logs */ ALL = 'ALL', } diff --git a/packages/aws-cdk-lib/aws-appsync/test/appsync.test.ts b/packages/aws-cdk-lib/aws-appsync/test/appsync.test.ts index 015491c97e891..87950c2d6c827 100644 --- a/packages/aws-cdk-lib/aws-appsync/test/appsync.test.ts +++ b/packages/aws-cdk-lib/aws-appsync/test/appsync.test.ts @@ -370,4 +370,28 @@ test('when resolver limit is out of range, it throws an error', () => { expect(() => buildWithLimit('resolver-limit-max', 10000)).not.toThrow(errorString); expect(() => buildWithLimit('resolver-limit-high', 10001)).toThrow(errorString); -}); \ No newline at end of file +}); + +test.each([ + [appsync.FieldLogLevel.ALL], + [appsync.FieldLogLevel.ERROR], + [appsync.FieldLogLevel.NONE], + [appsync.FieldLogLevel.INFO], + [appsync.FieldLogLevel.DEBUG], +])('GraphQLApi with LogLevel %s', (fieldLogLevel) => { + // WHEN + new appsync.GraphqlApi(stack, 'GraphQLApi', { + name: 'api', + schema: appsync.SchemaFile.fromAsset(path.join(__dirname, 'appsync.test.graphql')), + logConfig: { + fieldLogLevel, + }, + }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLApi', { + LogConfig: { + FieldLogLevel: fieldLogLevel, + }, + }); +});