我如何调试 AWS Api 网关和 Lambda 的 "AWS/ApiGateway 5XXError"
How do I debug AWS Api Gateway & Lambda's "AWS/ApiGateway 5XXError"
我有一个运行 lambda 函数的 API 网关资源。我正在使用来自我的 Api 网关的 AWS 生成的 SDK 调用 API 网关资源。
这是来自我的客户的似乎相关的堆栈跟踪部分:
Caused by: com.amazonaws.mobileconnectors.apigateway.ApiClientException: {"message": "Internal server error"} (Service: DevnetcountableClient; Status Code: 500; Error Code: null; Request ID: 348e8f98-6f55-11e6-97f6-098c2caf220f)
at com.amazonaws.mobileconnectors.apigateway.ApiClientHandler.handleResponse(ApiClientHandler.java:255) at com.amazonaws.mobileconnectors.apigateway.ApiClientHandler.invoke(ApiClientHandler.java:88)
at java.lang.reflect.Proxy.invoke(Proxy.java:393)
at $Proxy1.accountCreatePost(Unknown Source)
现在查看 AWS 控制台,在我的 Api 网关仪表板中,我看到请求进入并导致 "AWS/ApiGateway 5XXError"。但是有 0 个日志(我可以找到)。我的 lambda 函数似乎没有被调用,也没有显示 lambda 日志。
现在这就是我的 lambda 的样子:
module.exports.createAccount = function(event, context, cb) {
console.log('createAccount');
console.log(event);
console.log(context);
console.log(cb);
cb(null, {status: 'SUCCESS', message: 'I ran!'});
};
我该如何调试?
编辑:好的,这里是将所有内容组合在一起的 cloudformation 脚本。
{
"AWSTemplateFormatVersion":"2010-09-09",
"Description":"The AWS CloudFormation template for this Serverless application",
"Resources":{
"ServerlessDeploymentBucket":{
"Type":"AWS::S3::Bucket"
},
"IamRoleLambda":{
"Type":"AWS::IAM::Role",
"Properties":{
"AssumeRolePolicyDocument":{
"Version":"2012-10-17",
"Statement":[
{
"Effect":"Allow",
"Principal":{
"Service":[
"lambda.amazonaws.com"
]
},
"Action":[
"sts:AssumeRole"
]
}
]
},
"Path":"/"
}
},
"IamPolicyLambda":{
"Type":"AWS::IAM::Policy",
"Properties":{
"PolicyName":"dev-coolsoftware-lambda",
"PolicyDocument":{
"Version":"2012-10-17",
"Statement":[
{
"Effect":"Allow",
"Action":[
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource":"arn:aws:logs:us-west-2:*:*"
}
]
},
"Roles":[
{
"Ref":"IamRoleLambda"
}
]
}
},
"createAccount":{
"Type":"AWS::Lambda::Function",
"Properties":{
"Code":{
"S3Bucket":{
"Ref":"ServerlessDeploymentBucket"
},
"S3Key":"coolsoftware-1472853507538.zip"
},
"FunctionName":"coolsoftware-dev-createAccount",
"Handler":"handler.createAccount",
"MemorySize":128,
"Role":{
"Fn::GetAtt":[
"IamRoleLambda",
"Arn"
]
},
"Runtime":"nodejs4.3",
"Timeout":30
}
},
"RestApiApigEvent":{
"Type":"AWS::ApiGateway::RestApi",
"Properties":{
"Name":"dev-coolsoftware"
}
},
"ResourceApigEventCreateaccountAccount":{
"Type":"AWS::ApiGateway::Resource",
"Properties":{
"ParentId":{
"Fn::GetAtt":[
"RestApiApigEvent",
"RootResourceId"
]
},
"PathPart":"account",
"RestApiId":{
"Ref":"RestApiApigEvent"
}
}
},
"PutMethodApigEventCreateaccountAccount":{
"Type":"AWS::ApiGateway::Method",
"Properties":{
"AuthorizationType":"AWS_IAM",
"HttpMethod":"PUT",
"MethodResponses":[
{
"ResponseModels":{
"application/json":"AccountCreationResponseModel"
},
"ResponseParameters":{
},
"StatusCode":"200"
}
],
"RequestParameters":{
},
"Integration":{
"IntegrationHttpMethod":"POST",
"Type":"AWS",
"Uri":{
"Fn::Join":[
"",
[
"arn:aws:apigateway:",
{
"Ref":"AWS::Region"
},
":lambda:path/2015-03-31/functions/",
{
"Fn::GetAtt":[
"createAccount",
"Arn"
]
},
"/invocations"
]
]
},
"RequestTemplates":{
"application/json":"\n #define( $loop )\n {\n #foreach($key in $map.keySet())\n \"$util.escapeJavaScript($key)\":\n \"$util.escapeJavaScript($map.get($key))\"\n #if( $foreach.hasNext ) , #end\n #end\n }\n #end\n {\n \"body\": $input.json(\"$\"),\n \"method\": \"$context.httpMethod\",\n \"principalId\": \"$context.authorizer.principalId\",\n \"stage\": \"$context.stage\",\n\n #set( $map = $input.params().header )\n \"headers\": $loop,\n\n #set( $map = $input.params().querystring )\n \"query\": $loop,\n\n #set( $map = $input.params().path )\n \"path\": $loop,\n\n #set( $map = $context.identity )\n \"identity\": $loop,\n\n #set( $map = $stageVariables )\n \"stageVariables\": $loop\n }\n "
},
"IntegrationResponses":[
{
"StatusCode":"200",
"ResponseParameters":{
},
"ResponseTemplates":{
"application/json":""
}
}
]
},
"ResourceId":{
"Ref":"ResourceApigEventCreateaccountAccount"
},
"RestApiId":{
"Ref":"RestApiApigEvent"
},
"RequestModels":{
"application/json":"AccountCreationRequestModel"
}
}
},
"DeploymentApigEvent1472853508283":{
"Type":"AWS::ApiGateway::Deployment",
"Properties":{
"RestApiId":{
"Ref":"RestApiApigEvent"
},
"StageName":"dev"
},
"DependsOn":[
"PutMethodApigEventCreateaccountAccount"
]
},
"createAccountApigPermission":{
"Type":"AWS::Lambda::Permission",
"Properties":{
"FunctionName":{
"Fn::GetAtt":[
"createAccount",
"Arn"
]
},
"Action":"lambda:InvokeFunction",
"Principal":"apigateway.amazonaws.com"
}
},
"DynamoDBTableAccounts":{
"Type":"AWS::DynamoDB::Table",
"DeletionPolicy":"Retain",
"Properties":{
"TableName":"dev-coolsoftware-accounts",
"ProvisionedThroughput":{
"ReadCapacityUnits":1,
"WriteCapacityUnits":1
},
"AttributeDefinitions":[
{
"AttributeName":"accountid",
"AttributeType":"S"
}
],
"KeySchema":[
{
"AttributeName":"accountid",
"KeyType":"HASH"
}
]
}
},
"AccountCreationRequestModel":{
"Type":"AWS::ApiGateway::Model",
"Properties":{
"RestApiId":{
"Ref":"RestApiApigEvent"
},
"ContentType":"application/json",
"Description":"Schema for AccountCreationRequestModel",
"Name":"AccountCreationRequestModel",
"Schema":{
"$schema":"http://json-schema.org/draft-04/schema#",
"title":"AccountCreationRequestModel",
"type":"object",
"properties":{
"publickey":{
"type":"string"
},
"deviceid":{
"type":"string"
}
}
}
}
},
"AccountCreationResponseModel":{
"Type":"AWS::ApiGateway::Model",
"Properties":{
"RestApiId":{
"Ref":"RestApiApigEvent"
},
"ContentType":"application/json",
"Description":"Schema for AccountCreationResponseModel",
"Name":"AccountCreationResponseModel",
"Schema":{
"$schema":"http://json-schema.org/draft-04/schema#",
"title":"AccountCreationResponseModel",
"type":"object",
"properties":{
"status":{
"type":"string"
},
"message":{
"type":"string"
}
}
}
}
},
"FailureResponseModel":{
"Type":"AWS::ApiGateway::Model",
"Properties":{
"RestApiId":{
"Ref":"RestApiApigEvent"
},
"ContentType":"application/json",
"Description":"Schema for FailureResponseModel",
"Name":"FailureResponseModel",
"Schema":{
"$schema":"http://json-schema.org/draft-04/schema#",
"title":"FailureResponseModel",
"type":"object",
"properties":{
"status":{
"type":"string"
},
"message":{
"type":"string"
}
}
}
}
}
},
"Outputs":{
"ServerlessDeploymentBucketName":{
"Value":{
"Ref":"ServerlessDeploymentBucket"
}
},
"Function1Arn":{
"Description":"Lambda function info",
"Value":{
"Fn::GetAtt":[
"createAccount",
"Arn"
]
}
},
"ServiceEndpoint":{
"Description":"URL of the service endpoint",
"Value":{
"Fn::Join":[
"",
[
"https://",
{
"Ref":"RestApiApigEvent"
},
".execute-api.us-west-2.amazonaws.com/dev"
]
]
}
}
}
}
编辑 2:当我在 AWS 控制台中使用 API 网关的测试功能测试端点时,一切正常:/
编辑 3:再次更新了 cloudformation 脚本——仍然无效。
如何调试:
- 创建 IAM 角色以允许 API 网关将日志推送到 CloudWatch。该角色必须附加以下策略:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:DescribeLogGroups",
"logs:DescribeLogStreams",
"logs:PutLogEvents",
"logs:GetLogEvents",
"logs:FilterLogEvents"
],
"Resource": "*"
}
]
}
具有以下信任策略:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "apigateway.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
在您 API 区域的 API 网关控制台中:转到设置 >>> 输入 API 网关-CloudWatch 日志记录的 ARN角色 >>> 单击 'Save'
进入你API的舞台。在 'CloudWatch Settings'、select 'Enable CloudWatch Logs' 下。将 'Log level' 设置为 'INFO'。 Select 'Log full requests/responses data'.
将您的 API 重新部署到该阶段:转到 API 的 'Resources' 选项卡。 Select 操作 >>> 部署 API.
发出请求,等待几分钟,然后查看日志内容(在 CloudWatch 中)。
错误:
原因:
使用 Credentials: 'arn:aws:iam::*:user/*'
启用 "Invoke with caller credentials" 后,调用方的 IAM 角色无权调用 lambda 函数。这导致了 500 错误。一旦我授予调用者的 IAM 角色访问权限,一切就开始正常工作了。
API 网关日志显示什么?它显示 "Invalid permissions on Lambda function" 吗?我认为您需要在 CloudFormation 模板中包含权限创建(资源)。这是我的一个:
"PERMISSIONGET": {
"Type": "AWS::Lambda::Permission",
"Properties": {
"FunctionName": "createCabinet",
"Action": "lambda:InvokeFunction",
"Principal": "apigateway.amazonaws.com",
"SourceArn": {
"Fn::Join": [
"",
[
"arn:aws:execute-api:us-east-1:87875636623:",
{
"Ref": "APIGATEWAY"
},
"/*/GET/*"
]
]
}
},
"DependsOn": "APIDEPLOYMENT"
}
以防万一有人需要。
以下 link 说明如何启用 cloudwatch 日志以调试 api 网关问题。
https://kennbrodhagen.net/2016/07/23/how-to-enable-logging-for-api-gateway/
我有一个运行 lambda 函数的 API 网关资源。我正在使用来自我的 Api 网关的 AWS 生成的 SDK 调用 API 网关资源。
这是来自我的客户的似乎相关的堆栈跟踪部分:
Caused by: com.amazonaws.mobileconnectors.apigateway.ApiClientException: {"message": "Internal server error"} (Service: DevnetcountableClient; Status Code: 500; Error Code: null; Request ID: 348e8f98-6f55-11e6-97f6-098c2caf220f)
at com.amazonaws.mobileconnectors.apigateway.ApiClientHandler.handleResponse(ApiClientHandler.java:255) at com.amazonaws.mobileconnectors.apigateway.ApiClientHandler.invoke(ApiClientHandler.java:88)
at java.lang.reflect.Proxy.invoke(Proxy.java:393)
at $Proxy1.accountCreatePost(Unknown Source)
现在查看 AWS 控制台,在我的 Api 网关仪表板中,我看到请求进入并导致 "AWS/ApiGateway 5XXError"。但是有 0 个日志(我可以找到)。我的 lambda 函数似乎没有被调用,也没有显示 lambda 日志。
现在这就是我的 lambda 的样子:
module.exports.createAccount = function(event, context, cb) {
console.log('createAccount');
console.log(event);
console.log(context);
console.log(cb);
cb(null, {status: 'SUCCESS', message: 'I ran!'});
};
我该如何调试?
编辑:好的,这里是将所有内容组合在一起的 cloudformation 脚本。
{
"AWSTemplateFormatVersion":"2010-09-09",
"Description":"The AWS CloudFormation template for this Serverless application",
"Resources":{
"ServerlessDeploymentBucket":{
"Type":"AWS::S3::Bucket"
},
"IamRoleLambda":{
"Type":"AWS::IAM::Role",
"Properties":{
"AssumeRolePolicyDocument":{
"Version":"2012-10-17",
"Statement":[
{
"Effect":"Allow",
"Principal":{
"Service":[
"lambda.amazonaws.com"
]
},
"Action":[
"sts:AssumeRole"
]
}
]
},
"Path":"/"
}
},
"IamPolicyLambda":{
"Type":"AWS::IAM::Policy",
"Properties":{
"PolicyName":"dev-coolsoftware-lambda",
"PolicyDocument":{
"Version":"2012-10-17",
"Statement":[
{
"Effect":"Allow",
"Action":[
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource":"arn:aws:logs:us-west-2:*:*"
}
]
},
"Roles":[
{
"Ref":"IamRoleLambda"
}
]
}
},
"createAccount":{
"Type":"AWS::Lambda::Function",
"Properties":{
"Code":{
"S3Bucket":{
"Ref":"ServerlessDeploymentBucket"
},
"S3Key":"coolsoftware-1472853507538.zip"
},
"FunctionName":"coolsoftware-dev-createAccount",
"Handler":"handler.createAccount",
"MemorySize":128,
"Role":{
"Fn::GetAtt":[
"IamRoleLambda",
"Arn"
]
},
"Runtime":"nodejs4.3",
"Timeout":30
}
},
"RestApiApigEvent":{
"Type":"AWS::ApiGateway::RestApi",
"Properties":{
"Name":"dev-coolsoftware"
}
},
"ResourceApigEventCreateaccountAccount":{
"Type":"AWS::ApiGateway::Resource",
"Properties":{
"ParentId":{
"Fn::GetAtt":[
"RestApiApigEvent",
"RootResourceId"
]
},
"PathPart":"account",
"RestApiId":{
"Ref":"RestApiApigEvent"
}
}
},
"PutMethodApigEventCreateaccountAccount":{
"Type":"AWS::ApiGateway::Method",
"Properties":{
"AuthorizationType":"AWS_IAM",
"HttpMethod":"PUT",
"MethodResponses":[
{
"ResponseModels":{
"application/json":"AccountCreationResponseModel"
},
"ResponseParameters":{
},
"StatusCode":"200"
}
],
"RequestParameters":{
},
"Integration":{
"IntegrationHttpMethod":"POST",
"Type":"AWS",
"Uri":{
"Fn::Join":[
"",
[
"arn:aws:apigateway:",
{
"Ref":"AWS::Region"
},
":lambda:path/2015-03-31/functions/",
{
"Fn::GetAtt":[
"createAccount",
"Arn"
]
},
"/invocations"
]
]
},
"RequestTemplates":{
"application/json":"\n #define( $loop )\n {\n #foreach($key in $map.keySet())\n \"$util.escapeJavaScript($key)\":\n \"$util.escapeJavaScript($map.get($key))\"\n #if( $foreach.hasNext ) , #end\n #end\n }\n #end\n {\n \"body\": $input.json(\"$\"),\n \"method\": \"$context.httpMethod\",\n \"principalId\": \"$context.authorizer.principalId\",\n \"stage\": \"$context.stage\",\n\n #set( $map = $input.params().header )\n \"headers\": $loop,\n\n #set( $map = $input.params().querystring )\n \"query\": $loop,\n\n #set( $map = $input.params().path )\n \"path\": $loop,\n\n #set( $map = $context.identity )\n \"identity\": $loop,\n\n #set( $map = $stageVariables )\n \"stageVariables\": $loop\n }\n "
},
"IntegrationResponses":[
{
"StatusCode":"200",
"ResponseParameters":{
},
"ResponseTemplates":{
"application/json":""
}
}
]
},
"ResourceId":{
"Ref":"ResourceApigEventCreateaccountAccount"
},
"RestApiId":{
"Ref":"RestApiApigEvent"
},
"RequestModels":{
"application/json":"AccountCreationRequestModel"
}
}
},
"DeploymentApigEvent1472853508283":{
"Type":"AWS::ApiGateway::Deployment",
"Properties":{
"RestApiId":{
"Ref":"RestApiApigEvent"
},
"StageName":"dev"
},
"DependsOn":[
"PutMethodApigEventCreateaccountAccount"
]
},
"createAccountApigPermission":{
"Type":"AWS::Lambda::Permission",
"Properties":{
"FunctionName":{
"Fn::GetAtt":[
"createAccount",
"Arn"
]
},
"Action":"lambda:InvokeFunction",
"Principal":"apigateway.amazonaws.com"
}
},
"DynamoDBTableAccounts":{
"Type":"AWS::DynamoDB::Table",
"DeletionPolicy":"Retain",
"Properties":{
"TableName":"dev-coolsoftware-accounts",
"ProvisionedThroughput":{
"ReadCapacityUnits":1,
"WriteCapacityUnits":1
},
"AttributeDefinitions":[
{
"AttributeName":"accountid",
"AttributeType":"S"
}
],
"KeySchema":[
{
"AttributeName":"accountid",
"KeyType":"HASH"
}
]
}
},
"AccountCreationRequestModel":{
"Type":"AWS::ApiGateway::Model",
"Properties":{
"RestApiId":{
"Ref":"RestApiApigEvent"
},
"ContentType":"application/json",
"Description":"Schema for AccountCreationRequestModel",
"Name":"AccountCreationRequestModel",
"Schema":{
"$schema":"http://json-schema.org/draft-04/schema#",
"title":"AccountCreationRequestModel",
"type":"object",
"properties":{
"publickey":{
"type":"string"
},
"deviceid":{
"type":"string"
}
}
}
}
},
"AccountCreationResponseModel":{
"Type":"AWS::ApiGateway::Model",
"Properties":{
"RestApiId":{
"Ref":"RestApiApigEvent"
},
"ContentType":"application/json",
"Description":"Schema for AccountCreationResponseModel",
"Name":"AccountCreationResponseModel",
"Schema":{
"$schema":"http://json-schema.org/draft-04/schema#",
"title":"AccountCreationResponseModel",
"type":"object",
"properties":{
"status":{
"type":"string"
},
"message":{
"type":"string"
}
}
}
}
},
"FailureResponseModel":{
"Type":"AWS::ApiGateway::Model",
"Properties":{
"RestApiId":{
"Ref":"RestApiApigEvent"
},
"ContentType":"application/json",
"Description":"Schema for FailureResponseModel",
"Name":"FailureResponseModel",
"Schema":{
"$schema":"http://json-schema.org/draft-04/schema#",
"title":"FailureResponseModel",
"type":"object",
"properties":{
"status":{
"type":"string"
},
"message":{
"type":"string"
}
}
}
}
}
},
"Outputs":{
"ServerlessDeploymentBucketName":{
"Value":{
"Ref":"ServerlessDeploymentBucket"
}
},
"Function1Arn":{
"Description":"Lambda function info",
"Value":{
"Fn::GetAtt":[
"createAccount",
"Arn"
]
}
},
"ServiceEndpoint":{
"Description":"URL of the service endpoint",
"Value":{
"Fn::Join":[
"",
[
"https://",
{
"Ref":"RestApiApigEvent"
},
".execute-api.us-west-2.amazonaws.com/dev"
]
]
}
}
}
}
编辑 2:当我在 AWS 控制台中使用 API 网关的测试功能测试端点时,一切正常:/
编辑 3:再次更新了 cloudformation 脚本——仍然无效。
如何调试:
- 创建 IAM 角色以允许 API 网关将日志推送到 CloudWatch。该角色必须附加以下策略:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:DescribeLogGroups",
"logs:DescribeLogStreams",
"logs:PutLogEvents",
"logs:GetLogEvents",
"logs:FilterLogEvents"
],
"Resource": "*"
}
]
}
具有以下信任策略:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "apigateway.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
在您 API 区域的 API 网关控制台中:转到设置 >>> 输入 API 网关-CloudWatch 日志记录的 ARN角色 >>> 单击 'Save'
进入你API的舞台。在 'CloudWatch Settings'、select 'Enable CloudWatch Logs' 下。将 'Log level' 设置为 'INFO'。 Select 'Log full requests/responses data'.
将您的 API 重新部署到该阶段:转到 API 的 'Resources' 选项卡。 Select 操作 >>> 部署 API.
发出请求,等待几分钟,然后查看日志内容(在 CloudWatch 中)。
错误:
原因:
使用 Credentials: 'arn:aws:iam::*:user/*'
启用 "Invoke with caller credentials" 后,调用方的 IAM 角色无权调用 lambda 函数。这导致了 500 错误。一旦我授予调用者的 IAM 角色访问权限,一切就开始正常工作了。
API 网关日志显示什么?它显示 "Invalid permissions on Lambda function" 吗?我认为您需要在 CloudFormation 模板中包含权限创建(资源)。这是我的一个:
"PERMISSIONGET": {
"Type": "AWS::Lambda::Permission",
"Properties": {
"FunctionName": "createCabinet",
"Action": "lambda:InvokeFunction",
"Principal": "apigateway.amazonaws.com",
"SourceArn": {
"Fn::Join": [
"",
[
"arn:aws:execute-api:us-east-1:87875636623:",
{
"Ref": "APIGATEWAY"
},
"/*/GET/*"
]
]
}
},
"DependsOn": "APIDEPLOYMENT"
}
以防万一有人需要。
以下 link 说明如何启用 cloudwatch 日志以调试 api 网关问题。
https://kennbrodhagen.net/2016/07/23/how-to-enable-logging-for-api-gateway/