How to debug aws lambda functions written in node js

北城以北 提交于 2020-01-12 14:31:36

问题


We have been developing AWS Lambda functions in Node JS for a few months. Can we debug, i.e. step through the Node JS code as we can with .Net C# code in Visual Studio?


回答1:


IDE-based development tools are not available by default for many Lambda functions. There are some plugins, such as the Visual Studio support introduced by AWS on their blog at https://aws.amazon.com/blogs/developer/aws-lambda-support-in-visual-studio/, but these will have varying levels of feature sets and support.

In order to test Lambda using step debugging, you'll need to focus on two domains - the hardware on which it runs, and the way in which your Lambda function is invoked. The hardware is challenging to emulate, as AWS keeps the particulars of the machine instances that run your lambda functions secret. As such, when it comes to emulating hardware, you'll simply need to keep within what's reasonable for your language and operating system - make sure that the correct run time is installed (as in, don't install NodeJS 4.X when you're working with the version 6 runtime), make sure you don't exceed storage requirements (AMIs for Lambda get 500 MB of temporary storage space in /tmp), and ensure you're not saving any state locally prior to runs of your code.

Once you've nailed down your machine requirements (or decided to pass on them as your code doesn't do any hardware-specific work), then you'll need to write a test harness to invoke your AWS Lambda function. This test harness serves as an entry point for your debugger, and while it is most likely not 100% accurate with respect to how AWS invokes Lambda (for example, the context parameter contains information on your current Lambda invocation, which will by nature vary between executions), it gets you to the point where you can invoke all of your standard coding support tools.

Note: the following simple test harness is written for Node.JS, but you can adapt the concepts to the runtime in which your Lambda executes

A Simple Test Harness for AWS Lambda (Node.js)

The first thing we'll do is create a new file - debug.js - and import the handler function prototype. Assuming you've defined your handler in handler.js, and called it handler, you do that as follows:

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

Next, we need to invoke the handler function. As I alluded to above, each of the parameters has a different purpose. The first parameter to the handler -event - has details of the event causing the invocation. Note: This also includes your function arguments. The second parameter, as we discussed, contains information on the context in which your function is running. There's also a third parameter, callback, that can be used to invoke a callback upon completion of your Lambda execution. Review the AWS docs here: http://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-handler.html

So for our purposes, for a simple test harness, we just need to send the parameters through in the event parameter. We'll leave the context and callback parameters alone for now (with a minor modification, more on that below), but if you want to provide extra data there that your function relies upon that's fine - just make sure it doesn't conflict with any of the automated data put there in AWS. So we define the parameter hash, and invoke the function, using the following code in debug.js:

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);
}});

This code does a few interesting things:

  • It overloads the context object with a success and fail handler. You can wrap these in an "if" statement, and invoke them in your Lambda code using context.succeed(message) or context.fail(error). These are not officially supported by Lambda, but are instead used as a workaround in our code to get access to success/fail behavior
    • Handlers call process.exit() with the appropriate error code. This allows you to chain your execution into CI/CD tools, or any other batch processing tools that use process exit code as control flow

Once you've written this simple test harness, and adapted your Lambda code to invoke the success/fail handler if they are present (something as simple as if(context.success){context.success(args);} should be sufficient), you can now invoke the lambda function using node debug.js and see the results in the console.

I've also had great luck with unit testing in my Lambda functions. As you now have an entry point, and an example of how to call the Lambda function, you should be able to write suitable unit and function tests that express all of your functionality.

A quick note on shortcomings

As I mentioned, this approach isn't perfect. Here are a few problems with the test harness that could potentially arise:

  • We haven't done any emulation of the context object. You can see the parameters available in the context object at http://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-context.html - you'll need to do some trial and error to figure out exactly what format ends up in these parameters
  • We have not done any machine emulation, to catch hardware issues
  • We've only covered Node.js functions here, other languages may have trouble adapting the callback approach
  • We've overloaded the context mechanism to provide our success-fail handlers. If AWS adds similarly-named member objects to the context object, this approach may run into problems

However, despite the above, you should now have the capability to use local debugging tools to test and debug your Lambda functions. We use a similar framework at Backand - https://www.backand.com - for our Lambda function development tool, and it has greatly increased our Lambda development velocity.




回答2:


I would like to share what I have found as I had had some hard time trying to find it out. The solution is based on what I found on article "Debugging AWS Lambda Functions Locally using VS Code and lambda-local"(https://www.codeproject.com/Articles/1163890/Debugging-AWS-Lambda-functions-locally-using-VS-Co) with some modification in order to work in our Windows based environment.

Here is the summary:

1) To use Visual Studio Code to lunch a debug session. Am example of launch.json for debugging 'llDebugDetail.js' is as below:

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

2) To use the lambda-local framework to call (execute) the lambda function. The lambda-local framework has to be installed locally, otherwise the VSC debugger won't find it. Our lambda function is invoked by calling the following URL: https://xxx.execute-api.ap-southeast-2.amazonaws.com/resourceName/{id}/detail. The {id} is a GUID parameter for selecting a product item and returning its details.

Here is the 'llDebugDetail.js' code for calling the 'getDetail' function for returning product details with the GUID as its id in the URL. The function is within the 'getDetail.js' file.

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);
});

With the above done, you can now set break points anywhere within your code, e.g. inside getDetail.js, launch the program and the step through the code from the break points within getDetail.js.




回答3:


Step through debugging is now possible with AWS Lambda with the Sigma IDE. Yes, you debug the function while its actually running within AWS - See the demo below https://serverless.asankha.com/2019/08/write-lambda-function-test-it-instantly.html




回答4:


You cannot debug the lambda code like you do in VS but you can invoke some test data and check everything is fine.

  1. You can run lambda locally in your machine using lambda-local and serverless-offline
  2. So invoke your lambda with some test event & data and you can log and see whats happening for different inputs



回答5:


Trek 10 released an interesting tool recently that allows stepping through node.js code live in AWS lambda functions! How, you may ask? "Magic and mirrors", according to them :-)

Apparently, it doesn't attach to Amazon's host process directly (which is impossible), but it forks your code into a child process running in debug mode and proxies connections to your local Chrome DevTools. (There is actually a little more to the configuration, which you can read about at the github repo below.)

Here's the announcement: https://www.trek10.com/blog/aws-lambda-debugger/

and the github repo: https://github.com/trek10inc/aws-lambda-debugger




回答6:


As others have pointed out, you can't natively step debug a Lambda. But new tools are being developed that make it possible. Rookout now offers step debugging of production Node.js Lambdas without forking or stopping the code, using some sort of bytecode-level method.




回答7:


Step debugging is not possible in case of Lambda. That's one of the downsides of using Lambda. You will have to rely on logging (log4j or whatever) for your debugging




回答8:


The easiest option I have so far with VS Code is this:

  1. Create a new file, lets say call it debug.js and just call your lambda function from here, something like this: const app = require('./index') app.handler()

  2. Change program entry of the launcher.json file like this: "program": "${workspaceFolder}/<your app dir>/debug.js"

  3. You can now just put a breakpoint on this line (app.handler()) and it works




回答9:


If you are using serverless and serverless offline plugin to test in local. You can refer below:

If you are using windows, update the vscode launch.json and package.json as below :

// 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"
  }

If on linux your debug script will be:

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



回答10:


Debugging lambda using breakpoints in VSCode:

First, write test cases for your handler as follows: 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')
    });
  });
});

Now add the VSCode debugger configuration

Step 1: Click on debugger icon on the left side

Step 2: Click Add configurations

and add the following configurations in launch.json file:

{
    "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"
      }
    ]
  }

Step 3: Now add a breakpoint to code which you wants to debug as follows:

Step 4: Now focus on the test file by clicking on the file:

Step 5: Choose the option from the drop-down "Mocha All" to run the complete solution and "Mocha current file" to run only selected file

Now click on the DEBUG Play button and enjoy the debugging!



来源:https://stackoverflow.com/questions/44403523/how-to-debug-aws-lambda-functions-written-in-node-js

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!