How to debug aws lambda functions written in node js

We've been developing AWS Lambda Functions in Node JS for several months now. Can we debug i.e. Step through Node JS code how can we with .Net C # code in Visual Studio?

+7


source to share


9 replies


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

To test Lambda with step-by-step debugging, you need to focus on two domains - the hardware it runs on and the way your Lambda function is called. Hardware is difficult to emulate because AWS keeps details of the machine instances on which your lambda functions run. So, when it comes to hardware emulation, you just have to stick with what's right for your language and operating system - make sure the correct runtime is set (like, for example, don't install NodeJS 4.X when you're working with version 6), make sure you don't exceed storage requirements (Lambda AMIs get 500MB of temporary storage in / tmp), and make sure you don't save any state locally before running your code.

After you have set the requirements for your machine (or decided to pass them over since your code does not do any hardware specific work), you need to write a test suite to call the AWS Lambda function. This test harness serves as the entry point for your debugger, and while it is most likely not 100% accurate as to how AWS calls Lambda (for example, a parameter context

contains information about your current Lambda call, which by its nature will vary depending on from execution), this brings you to the point where you can invoke all of your standard coding support tools.

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

Simple Test Suite for AWS Lambda (Node.js)

The first thing we do is create a new file - debug.js - and import the prototype of the handler function. Assuming you have defined your handler in handler.js and named it handler

, you do it like this:

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

Next, we need to call the handler function. As I mentioned above, each of the parameters has a different purpose. The first handler parameter - event

- contains details about the event that caused the call. Note: this also includes your function arguments. The second parameter, as we discussed, contains information about the context in which your function is running. There is also a third parameter, callback, that you can use to invoke a callback when Lambda has finished executing. Check out the AWS docs here: http://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-handler.html

So for our purposes, for simple testing, we just need to send parameters via a parameter event

. We will leave the parameters context

and callback

at rest (with minor changes, more on that below), but if you want to provide additional data that your function is used for this fine - just make sure it is. not interfere with any of the automated data hosted on AWS. Therefore, we define the hash of the parameter and call 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 couple of interesting things:

  • It overloads the context object with a success and failure handler. You can wrap them in an if statement and call them in your lambda code using context.succeed(message)

    or context.fail(error)

    . They are not officially supported by Lambda, but are instead used in our code as a workaround to access the success / failure behavior
    • Handlers call process.exit () with an appropriate error code. This allows you to link execution to CI / CD tools or any other batching tools that use process termination code as control flow

Once you have written this simple test suite and adapted your lambda code to call the success / failure handler if any (something as simple as it if(context.success){context.success(args);}

should be enough), you can now call the lambda function using node debug.js

and see results in console.

I also had good luck with unit testing in my Lambda functions. Now that you have an entry point and an example of how to call a Lambda function, you can write suitable unit and functional tests that express all of your functionality.

A quick note on disadvantages

As I said, this approach is not ideal. Here are some problems with the test suite that you might encounter:

  • We did not emulate the context object. You can see the options available in the context object at http://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-context.html - you will need to do some trial and error to figure out exactly which format ends with these parameters
  • We did not do any machine emulation to catch hardware problems
  • We've only covered Node.js functions here, other languages ​​may have problems adapting the callback method
  • We are overloaded with a contextual mechanism to provide our success-failure handlers. If AWS adds member objects with the same name to the object context

    , this approach can run into problems

However, notwithstanding the above, you should now be able to use local debugging tools to test and debug your Lambda functions. We use a similar structure in Backand - https://www.backand.com - for our Lambda function authoring tool and this has greatly increased our Lambda development speed.

+6


source


I would like to share what I found as I had a hard time finding it. The solution is based on what I found in 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 changes to work in our Windows environment.

Here's a summary:

1) To use Visual Studio Code for lunch, do a debug session. An example of running .json to debug 'llDebugDetail.js' is as follows:

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

      



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

Here is the code 'llDebugDetail.js' to call the getDetail function to return product details with a GUID as its ID in the URL. The function is located in 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, you can now set breakpoints anywhere in your code eg. inside getDetail.js, run the program and step through the code from breakpoints in getDetail.js.

+4


source


You cannot debug lambda code like in VS, but you can call some test data and check if everything is ok.

  • You can run lambda locally on your machine using lambda-local and serverless-offline
  • So, start your lambda with some test event and data and you can login and see what happens for different inputs.
+3


source


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

It does not appear to be tied to the Amazon host process directly (which is not possible), but it deploys your code into a child process running in debug mode and proxy connecting to your local Chrome DevTools. (There are actually a bit more settings you can read about in the github repository below.)

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

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

+1


source


As others have pointed out, you cannot debug a lambda step by step. But new tools are being developed that make this possible. Rookout now offers step-by-step debugging of production Node.js Lambdas without forking or stopping code using some bytecode-level technique.

+1


source


Debugging a step is not possible in the case of Lambda. This is one of the downsides to using Lambda. You will have to rely on logging (log4j or whatever) for your debugging

0


source


The simplest option I have with VS Code is as follows:

  1. Create a new file, say name it, debug.js

    and just call your lambda function from here, something like this: const app = require('./index') app.handler()

  2. Change the program entry in the file launcher.json

    as follows: "program": "${workspaceFolder}/<your app dir>/debug.js"

  3. Now you can just put a breakpoint on that line ( app.handler()

    ) and it works

0


source


If you are using a server and standalone plugin for local testing. You can link below:

If you are using Windows, update vscode launch.json and package.json as shown 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

       }

   ]

}
      

Run codeHide result


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

Run codeHide result


If on Linux your debug script would be:

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

      

0


source


Debugging lambda using breakpoints in VSCode:

First, write test cases for your handler like this: 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 config

Step 1: Click on the debugger icon on the left side

enter image description here

Step 2: Click Add Configurations

enter image description here

and add the following configurations to your 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 the code you want to debug like this:

enter image description here

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

Step 5: Select an option from the "Mocha All" dropdown to run the complete solution and "Mocha current file" to run only the selected file.

enter image description here

enter image description here

Now click on the DEBUG Play button and enjoy debugging!

0


source







All Articles