如何调试在节点js中编写的aws lambda函数

时间:2017-06-07 04:29:33

标签: node.js amazon-web-services debugging aws-lambda

我们一直在Node JS中开发AWS Lambda函数几个月。我们可以调试,即在Visual Studio中使用.Net C#代码逐步完成Node JS代码吗?

10 个答案:

答案 0 :(得分:6)

默认情况下,许多Lambda函数都不提供基于IDE的开发工具。有一些插件,例如AWS在其https://aws.amazon.com/blogs/developer/aws-lambda-support-in-visual-studio/博客上引入的Visual Studio支持,但这些插件将具有不同级别的功能集和支持。

为了使用步骤调试来测试Lambda,您需要关注两个域 - 运行它的硬件以及调用Lambda函数的方式。由于AWS保留了运行lambda函数的机器实例的详细信息,因此硬件难以模拟。因此,当涉及到模拟硬件时,您只需要保持对您的语言和操作系统合理的范围 - 确保安装正确的运行时间(如同,不要...当您使用版本6运行时,安装NodeJS 4.X),确保您不超过存储要求(Lambda的AMI在/ tmp中获得500 MB的临时存储空间),并确保您和#39;在运行代码之前,不要在本地保存任何状态。

一旦您确定了机器要求(或者决定传递它们,因为您的代码没有执行任何特定于硬件的工作),那么您需要编写测试工具来调用您的AWS Lambda函数。此测试工具充当调试器的入口点,尽管AWS调用Lambda的方式很可能不是100%准确(例如,context参数包含有关当前Lambda调用的信息,这将是从执行的性质来看,它可以让你达到可以调用所有标准编码支持工具的程度。

注意:为Node.JS编写了以下简单测试工具,但您可以将概念调整为Lambda执行的运行时

AWS Lambda(Node.js)的简单测试工具

我们要做的第一件事是创建一个新文件 - debug.js - 并导入处理函数原型。假设您已在handler.js中定义了处理程序,并将其称为handler,则按以下方式执行:

var handler = require('./handler.js').handler;

接下来,我们需要调用处理函数。如上所述,每个参数都有不同的用途。处理程序的第一个参数 - event - 具有导致调用的事件的详细信息。 注意:这还包括您的函数参数。正如我们所讨论的,第二个参数包含有关运行函数的上下文的信息。还有第三个参数,回调,可用于在完成Lambda执行时调用回调。在此处查看AWS文档:http://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-handler.html

因此,对于我们的目的,对于简单的测试工具,我们只需要在event参数中发送参数。我们暂时保留contextcallback参数(稍作修改,下面会详细介绍),但如果您想提供额外数据,那么您的函数依赖于&# 39;很好 - 只是确保它不会与AWS中的任何自动数据发生冲突。因此,我们使用debug.js中的以下代码定义参数hash并调用该函数:

var parameters = {
    "key1":"val1",
    "object" :{},
    // other keys as necessary
};

handler(parameters, {succeed:function(result){
    console.log("success: ", JSON.stringify(result, null, 2));
    process.exit(0);
}, fail:function(error){
    console.error("error: ", error);
    process.exit(1);
}});

这段代码做了一些有趣的事情:

  • 使用成功和失败处理程序重载上下文对象。您可以将它们包装在" if"语句,并使用context.succeed(message)context.fail(error)在您的Lambda代码中调用它们。这些不是Lambda正式支持的,而是在我们的代码中用作变通方法来访问成功/失败行为
    • 处理程序使用适当的错误代码调用process.exit()。这允许您将执行链接到CI / CD工具或使用流程退出代码作为控制流的任何其他批处理工具

一旦你编写了这个简单的测试工具,并调整了你的Lambda代码来调用成功/失败处理程序(如果它们存在那么简单就足够了),你现在可以调用lambda函数使用if(context.success){context.success(args);}并在控制台中查看结果。

我的Lambda函数中的单元测试也很幸运。由于您现在有一个入口点,以及如何调用Lambda函数的示例,您应该能够编写表达所有功能的合适的单元和函数测试。

关于缺点的快速说明

正如我所提到的,这种方法并不完美。以下是可能出现的测试工具的一些问题:

  • 我们还没有对上下文对象进行任何模拟。您可以在http://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-context.html处查看上下文对象中可用的参数 - 您需要进行一些试验和错误,以确定哪些格式最终会在这些参数中结束
  • 我们还没有进行任何机器仿真,以捕捉硬件问题
  • 我们这里只介绍Node.js功能,其他语言可能无法适应回调方法
  • 我们重载了上下文机制,以提供成功失败的处理程序。如果AWS将类似命名的成员对象添加到node debug.js对象,则此方法可能会遇到问题

但是,尽管如此,您现在应该能够使用本地调试工具来测试和调试Lambda函数。我们在Backand使用类似的框架 - https://www.backand.com - 用于我们的Lambda函数开发工具,它大大提高了我们的Lambda开发速度。

答案 1 :(得分:4)

我想分享我发现的内容,因为我很难找到它。该解决方案基于我在文章&#34;在本地使用VS代码调试AWS Lambda函数和lambda-local&#34;(https://www.codeproject.com/Articles/1163890/Debugging-AWS-Lambda-functions-locally-using-VS-Co)进行了一些修改,以便在我们基于Windows的环境中工作。< / p>

以下是摘要:

1)使用Visual Studio Code为调试会话提供午餐。是用于调试的launch.json的示例&#39; llDebugDetail.js&#39;如下:

{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "node",
            "request": "launch",
            "name": "Launch Program",
            "program": "${workspaceRoot}/test/llDebugDetail.js",
            "cwd": "${workspaceRoot}"
        }
    ]
}

2)使用lambda-local框架调用(执行)lambda函数。 lambda本地框架必须在本地安装,否则VSC调试器无法找到它。通过调用以下URL调用我们的lambda函数: https://xxx.execute-api.ap-southeast-2.amazonaws.com/resourceName/ {ID} /细节。 {id}是一个GUID参数,用于选择产品项并返回其详细信息。

这是&#39; llDebugDetail.js&#39;用于调用&#39; getDetail&#39;的代码用于返回产品详细信息的函数,其中GUID作为URL中的id。该功能位于&#39; getDetail.js&#39;文件。

const lambdaLocal = require('lambda-local');
var path = require("path");
const myPath = path.join(__dirname, '../getDetail.js');
const testEvent = {
    "resource": "resourceName/12da3f7d-7ce2-433f-8659-5d7cd0d74d9a/detail",
    "pathParameters": {"id": "12da3f7d-7ce2-433f-8659-5d7cd0d74d9a"}
}

var lambdaFunc = require(myPath);

lambdaLocal.execute({
    event: testEvent,
    lambdaFunc: lambdaFunc, 
    lambdaHandler: "getDetail"
}).then(function(done) {
    console.log(done);
}).catch(function(err) {
    console.log(err);
});

完成上述操作后,您现在可以在代码中的任何位置设置断点,例如在getDetail.js中,启动程序并从getDetail.js中的断点开始执行代码。

答案 2 :(得分:4)

现在可以使用带有Sigma IDE的AWS Lambda逐步调试。是的,您可以在该函数实际在AWS中运行时对其进行调试-请参见下面的演示 https://serverless.asankha.com/2019/08/write-lambda-function-test-it-instantly.html

答案 3 :(得分:3)

您不能像在VS中那样调试lambda代码,但是您可以调用一些测试数据并检查一切正常。

  1. 您可以使用lambda-localserverless-offline
  2. 在您的计算机上本地运行lambda
  3. 所以用一些测试事件调用你的lambda&amp;数据,您可以记录并查看针对不同输入发生的事情

答案 4 :(得分:1)

Trek 10最近发布了一个有趣的工具,它允许在AWS lambda函数中直接执行node.js代码!怎么样,你可能会问? &#34;魔术和镜子&#34;,据他们说: - )

显然,它并没有直接附加到亚马逊的主机进程(这是不可能的),但它会将您的代码分配到以调试模式运行的子进程,并代理与本地Chrome DevTools的连接。 (实际上还有一些配置,您可以在下面的github repo中阅读。)

以下是公告: https://www.trek10.com/blog/aws-lambda-debugger/

和github回购: https://github.com/trek10inc/aws-lambda-debugger

答案 5 :(得分:1)

正如其他人指出的那样,您不能在本地对Lambda进行逐步调试。但是正在开发使之成为可能的新工具。 Rookout现在提供使用某种字节码级方法的生产Node.js Lambda的逐步调试,而无需派生或停止代码。

答案 6 :(得分:0)

Lambda无法进行步骤调试。这是使用Lambda的缺点之一。您将不得不依赖于日志记录(log4j或其他)来进行调试

答案 7 :(得分:0)

到目前为止,我对VS Code最简单的选择是:

  1. 创建一个新文件,假设将其命名为debug.js,然后从此处调用您的lambda函数,如下所示: const app = require('./index') app.handler()

  2. 像这样更改launcher.json文件的程序条目: "program": "${workspaceFolder}/<your app dir>/debug.js"

  3. 您现在可以在此行上放置一个断点(app.handler()),它就可以工作

答案 8 :(得分:0)

如果您使用无服务器和无服务器脱机插件在本地进行测试。 您可以在下面参考:

如果您使用的是Windows,请如下更新vscode launch.json和package.json:

// launch.json
{

    "version": "0.2.0",

   "configurations": [

       {

           "type": "node",

           "request": "launch",

           "name": "Debug Serverless",

           "cwd": "${workspaceFolder}",

           "runtimeExecutable": "npm",

           "runtimeArgs": [

               "run",

               "debug"

           ],

           "outFiles": [

               "${workspaceFolder}/handler.js"

           ],

           "port": 9229,

           "sourceMaps": true

       }

   ]

}

// package.json
....
"scripts": {
    "debug": "SET SLS_DEBUG=* && node --inspect %USERPROFILE%\\AppData\\Roaming\\npm\\node_modules\\serverless\\bin\\serverless offline -s dev"
  }

如果在Linux上,您的调试脚本将是:

// package.json
....
"scripts": {
    "debug": "export SLS_DEBUG=* && node --inspect /usr/local/bin/serverless offline -s dev"
  }

答案 9 :(得分:0)

使用VSCode中的断点调试lambda:

首先,为您的处理程序编写测试用例,如下所示: index.test.js

'use strict';

const handler = require('../index');

const chai = require('chai');

const { expect } = chai;

describe('debug demo', () => {
  it('should return success', () => {
    let event = {data: "some data"}
    handler(event, '', function(err, res) {
      expect(res.statusCode, '200')
    });
  });
});

现在添加VSCode调试器配置

步骤1: 点击左侧的调试器图标

enter image description here

步骤2: 点击添加配置

enter image description here

并在launch.json文件中添加以下配置:

{
    "version": "0.2.0",
    "configurations": [

      {
          "type": "node",
          "request": "launch",
          "name": "Mocha All",
          "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha",
          "args": [
              "--timeout",
              "999999",
              "--colors",
              "'${workspaceFolder}/lambda-codebase/**/test/*.test.js'"
          ],
          "console": "integratedTerminal",
          "internalConsoleOptions": "neverOpen"
      },
      {
          "type": "node",
          "request": "launch",
          "name": "Mocha Current File",
          "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha",
          "args": [
              "--timeout",
              "999999",
              "--colors",
              "${file}"
          ],
          "console": "integratedTerminal",
          "internalConsoleOptions": "neverOpen"
      }
    ]
  }

第3步: 现在,向要调试的代码添加一个断点,如下所示:

enter image description here

第4步: 现在,通过单击文件将重点放在测试文件上:

第5步: 从下拉菜单“全部Mocha”中选择选项以运行完整的解决方案,从“ Mocha当前文件”中选择仅运行选定的文件

enter image description here

enter image description here

现在单击DEBUG Play按钮并享受调试!