Node.js AWS Lambda中的节点可执行文件

Node.js AWS Lambda中的节点可执行文件,node.js,aws-lambda,sentry,Node.js,Aws Lambda,Sentry,我正在尝试构建一个AWS Lambda(节点)函数,该函数利用。到目前为止,我有一些类似于: const CLI = require("@sentry/cli"); const cli = new CLI(null, { org: '...', authToken: '...', }); exports.handler = async (event) => { const response = await cli.execute(["relea

我正在尝试构建一个AWS Lambda(节点)函数,该函数利用。到目前为止,我有一些类似于:

const CLI = require("@sentry/cli");

const cli = new CLI(null, {
  org: '...',
  authToken: '...',
});

exports.handler = async (event) => {
  const response = await cli.execute(["releases", "list"]);

  // ...create a release/deploy/etc...
};
但是,这在以下情况下失败:

/var/task/node_modules/@sentry/cli/sentry cli:无法执行二进制文件

似乎也存在类似的问题,建议更改可执行文件的权限

如何确保在将函数压缩/上载到AWS时不会剥离可执行文件的权限?

TL;博士 深潜 此答案是文档中概述的步骤的摘要以及需要这些步骤的原因和先决条件/调试工作流的其他解释。建议按照以下步骤上载具有其他依赖项的NodeJS项目。我已经用一个已经运行的现有AWS Lambda实例设计了这些步骤,以帮助限制调试时的错误范围(到AWS或Sentry)

(建议)现有项目的步骤 1.1在本地安装节点w/NPM(我假设您已经这样做了)。记下您的本地节点版本,并检查是否匹配AWS Lambda实例

$ node -v
1.2安装AWS CLI(必须是!

1.3使用以下配置AWS CLI:

$ aws configure
注意:如果需要为每个平台配置,也可以手动配置。我将省略这些细节,因为它们很简单

1.4尝试首先部署
hello world
Lambda
,然后查看在不使用
sentry cli软件包的情况下是否可以。如果它真的起作用,你知道哨兵可能是问题所在,而不是AWS

1.5安装Sentry CLI:

$ npm install @sentry/cli
1.6自动
sentry cli
配置:

$ sentry-cli login
1.7使用
$sentry cli info
验证您的
sentry cli
配置是否有效。如果没有,则需要遵循控制台输出中建议的步骤

$ sentry-cli info
1.8使用aws X射线sdk安装依赖项:

$ npm install aws-xray-sdk
1.8.1(可选)导航到项目根文件夹。这只是为了举例说明;当前版本的AWS SDK预装在Lambda中,但您可以使用此技术加载其他预构建的JavaScript软件包,或者出于兼容性原因(不适用)您确实需要早期版本的AWS SDK

1.8.2(健全性检查)检查根目录子文件夹中所有文件的权限是否具有可执行权限。尝试在本地运行项目,以查看可执行权限是否存在:

$ ls -l && node function.js
1.9本项目:

$ zip -r function.zip . // The .zip file must be **less than 50 MB**!
1.10使用aws命令行工具上传功能代码
更新功能代码
(这很重要,因为这将解决权限问题

$ aws lambda update-function-code --function-name my-function --zip-file fileb://function.zip
1.11如果操作成功,您将获得如下输出:

{
    "FunctionName": "my-function",
    "FunctionArn": "arn:aws:lambda:us-east-2:123456789012:function:my-function",
    "Runtime": "nodejs12.x",
    "Role": "arn:aws:iam::123456789012:role/lambda-role",
    "Handler": "index.handler",
    "CodeSha256": "Qf0hMc1I2di6YFMi9aXm3JtGTmcDbjniEuiYonYptAk=",
    "Version": "$LATEST",
    "TracingConfig": {
        "Mode": "Active"
    },
    "RevisionId": "983ed1e3-ca8e-434b-8dc1-7d72ebadd83d",
    ...
}
1.12例如,如果上传时出现错误,您可以按照文档进行操作。如果需要,请检查AWS日志

1.13在确认
更新功能代码
成功后,测试正在运行的lambda

$ aws lambda invoke --function-name my-function --payload '{"key1": "value1", "key2": "value2", "key3": "value3"}' output.txt
另一种可能的解决方案(不理想) 在使用运行
cli
config命令之前,使sentry cli可执行

备选方案:您也可以尝试使用此选项

使用Sentry节点NPM包进行重构 如果在上述步骤中,您注意到Sentry CLI是问题所在,您可以尝试在不使用此包的情况下重构代码。请改用,因为此NPM包是为NodeJ构建的,并且可能重构您的代码。Sentry节点可能更容易运行,但没有用于部署/发布的功能。从其
用法来看

Sentry的SDK与您的运行时环境挂钩,并自动报告错误、异常和拒绝

(注)带AWS Lambda文件的哨兵 Sentry建议使用
@Sentry/serverless
作为与AWS Lambda集成的包。如果不想重构代码,请使用

启用AWS Lambda集成后,节点SDK将:

  • 自动报告Lambda函数中的所有事件
  • 允许您使用TraceSampleRate修改事务采样率
  • 问题报告自动包括:
  • 指向cloudwatch日志的链接
  • 功能详细信息
    • 函数的sys.argv
    • AWS请求ID
    • 函数执行时间
    • 函数版本
注意事项:
  • .zip文件必须小于50MB。如果大于50MB,亚马逊建议将其上载到亚马逊简单存储服务(亚马逊S3)存储桶
  • .zip文件不能包含用C或C++编写的库。如果.zip文件包含C扩展库,例如Pillow(pIL)或NUMPY库,则建议使用AWS无服务器应用模型(AWS山姆)命令行接口(CLI)来构建部署包。
  • .zip文件必须包含函数代码和用于运行函数代码的任何依赖项(如果适用)如果函数仅依赖于标准库或AWS SDK库,则不需要在.zip文件中包含这些库。这些库包含在受支持的Lambda运行时环境中
  • 如果任何库使用本机代码,请使用Amazon Linux环境创建部署包。此外,请确保将本机代码(如果有的话)本地打包在与Lambda相同的平台上
  • 如果部署包包含本机库,则可以使用AWS无服务器应用程序模型(
    AWS SAM
    )构建部署包。可以使用AWS SAM CLI SAM
    build
    命令和
    --use container
    创建部署包。此选项构建部署包
    {
        "FunctionName": "my-function",
        "FunctionArn": "arn:aws:lambda:us-east-2:123456789012:function:my-function",
        "Runtime": "nodejs12.x",
        "Role": "arn:aws:iam::123456789012:role/lambda-role",
        "Handler": "index.handler",
        "CodeSha256": "Qf0hMc1I2di6YFMi9aXm3JtGTmcDbjniEuiYonYptAk=",
        "Version": "$LATEST",
        "TracingConfig": {
            "Mode": "Active"
        },
        "RevisionId": "983ed1e3-ca8e-434b-8dc1-7d72ebadd83d",
        ...
    }
    
    $ aws lambda invoke --function-name my-function --payload '{"key1": "value1", "key2": "value2", "key3": "value3"}' output.txt
    
    var exec = require('child_process').exec, child;    
    child = exec('chmod +x /var/task/node_modules/@sentry/cli/sentry-cli',
        function (error, stdout, stderr) {
            console.log('stdout: ' + stdout);
            console.log('stderr: ' + stderr);
            if (error !== null) {
                 console.log('exec error: ' + error);
            }
        });
    child();