如何调试 AWS Api Gateway 和 Lambda 的“AWS/ApiGateway 5XXError”
Posted
技术标签:
【中文标题】如何调试 AWS Api Gateway 和 Lambda 的“AWS/ApiGateway 5XXError”【英文标题】:How do I debug AWS Api Gateway & Lambda's "AWS/ApiGateway 5XXError" 【发布时间】:2017-01-07 18:25:41 【问题描述】:我有一个运行 lambda 函数的 API Gateway 资源。我正在使用我的 Api Gateway 中的 AWS Generated SDK 调用 API Gateway 资源。
这是来自我的客户端的堆栈跟踪部分似乎相关:
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 Gateway 仪表板中,我看到请求进入并导致“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 Gateway 的测试功能测试端点时,一切正常:/
编辑 3:再次更新 cloudformation 脚本 - 仍然无法正常工作。
【问题讨论】:
我因缺少集成而出现此类错误。但是如果不查看您是如何创建网关/lambda 的,就很难弄清楚。 嗯,可能就是这样。我使用无服务器框架生成它,但我试图通过 cloudformation 脚本包含请求/响应模型、身份验证并启用“使用调用者凭据调用”。也许这就是破坏它的原因。无服务器框架通过 cloudformation 完成所有工作。我来看看模板。谢谢 @RhythmicFistman 我已经添加了我的 cloudformation 脚本,你介意看一下吗? 【参考方案1】:如何调试:
-
创建一个 IAM 角色以允许 API Gateway 将日志推送到 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 Gateway 控制台中:转到设置 >>> 输入 API Gateway-CloudWatch 日志记录角色的 ARN >>> 单击“保存”
转到您的 API 阶段。在“CloudWatch 设置”下,选择“启用 CloudWatch 日志”。将“日志级别”设置为“信息”。选择“记录完整的请求/响应数据”。
将您的 API 重新部署到该阶段:转到您的 API 的“资源”选项卡。选择操作 >>> 部署 API。
发出请求,等待几分钟,然后查看日志的内容(在 CloudWatch 中)。
错误:
原因:
一旦我使用 Credentials: 'arn:aws:iam::*:user/*'
启用“使用调用方凭据调用”,调用方的 IAM 角色就无权调用 lambda 函数。这导致了 500 错误。一旦我授予调用者的 IAM 角色访问权限,一切就开始正常工作了。
【讨论】:
现在您可以使用托管策略,而不是创建自己的策略。它被称为AmazonAPIGatewayPushToCloudWatchLogs
。
您能否详细说明如何解决错误 500,尤其是调用者的 IAM 角色访问权限中的内容?谢谢。
我想知道当我的代码在 AWS Api Gateway 中运行时如何在本地机器上打断点?有可能吗?【参考方案2】:
以防万一有人需要。
以下链接说明了如何启用 cloudwatch 日志以调试 api 网关问题。
https://kennbrodhagen.net/2016/07/23/how-to-enable-logging-for-api-gateway/
【讨论】:
【参考方案3】:API 网关日志显示什么?它是否显示“Lambda 函数的权限无效”?我认为您需要在 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"
【讨论】:
我已经解决了这个问题(请参阅下面的答案)。调用者凭据需要调用 lambda 函数的权限,因为在 API 网关中我启用了“使用调用者凭据调用”以上是关于如何调试 AWS Api Gateway 和 Lambda 的“AWS/ApiGateway 5XXError”的主要内容,如果未能解决你的问题,请参考以下文章
API 创新不会触发 AWS API Gateway 的基于自定义请求的 lambda 授权方
如果在 Terraform 模块中创建了 aws_api_gateway_integration,如何在 aws_api_gateway_deployment 资源上填充depends_on?
HTTP 请求正文未通过 AWS API Gateway 访问 AWS lambda 函数