【问题标题】:How do I debug AWS Api Gateway & Lambda's "AWS/ApiGateway 5XXError"如何调试 AWS Api Gateway 和 Lambda 的“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 脚本,你介意看一下吗?

标签: amazon-web-services aws-lambda aws-api-gateway serverless-framework


【解决方案1】:

如何调试:

  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"
    }
  ]
}
  1. 在您的 API 区域的 API Gateway 控制台中:转到设置 >>> 输入 API Gateway-CloudWatch 日志记录角色的 ARN >>> 单击“保存”

  2. 转到您的 API 阶段。在“CloudWatch 设置”下,选择“启用 CloudWatch 日志”。将“日志级别”设置为“信息”。选择“记录完整的请求/响应数据”。

  1. 将您的 API 重新部署到该阶段:转到您的 API 的“资源”选项卡。选择操作 >>> 部署 API。

  2. 发出请求,等待几分钟,然后查看日志的内容(在 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 网关中我启用了“使用调用者凭据调用”
    猜你喜欢
    • 2017-12-07
    • 2017-09-19
    • 1970-01-01
    • 2017-08-24
    • 1970-01-01
    • 1970-01-01
    • 2021-01-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多