Reputation: 1582
During this weekend i was running some node functions on aws lambda integrated with dynamodb, im using x-ray to debug it creating my own annotations, i like to know if there is a better approach to debug lambda functions something like a step-by-step?
Upvotes: 22
Views: 32011
Reputation: 1240
To debug AWS Lambda locally in Node.js or TypeScript, you can use the "Lambda as a Server" (LAAS) approach. This allows you to run Lambda functions locally as a server. Here's how:
Lambda Function (lambdas/CreatePostLambda.ts):
export const handler = async (event) => {
const { title, content } = JSON.parse(event.body);
return {
statusCode: 201,
body: JSON.stringify({ message: 'Post created successfully', title, content }),
};
};
Vite Config (vite.config.ts):
import { defineConfig } from 'vite';
import { handler as CreatePostLambda } from './lambdas/CreatePostLambda';
export default defineConfig({
server: { port: 8080 },
plugins: [
{
name: 'lambda-invoker',
configureServer(server) {
server.middlewares.use(async (req, res) => {
if (req.method === 'POST' && req.url === '/v1/posts') {
const event = { httpMethod: 'POST', body: await getRequestBody(req) };
const result = await CreatePostLambda(event, {});
res.statusCode = result.statusCode;
res.end(result.body);
} else {
res.statusCode = 404;
res.end('Not Found');
}
});
},
},
],
});
async function getRequestBody(req) {
return new Promise((resolve) => {
let body = '';
req.on('data', (chunk) => (body += chunk.toString()));
req.on('end', () => resolve(body));
});
}
How to Run
git clone https://github.com/serverless-typescript/examples.git
cd examples/lambda-local-debug
npm install
npx vite
Test your Lambda at http://localhost:8080.
Upvotes: 0
Reputation: 391
You can use the serverless framework to debug the function. In this approach, you don't have to install docker.
"scripts": {
"start": "serverless offline -s dev",
"test": "mocha"
}
use following code as launch.json if you use vscode (Fill you aws profile name in #PROFILENAME#)
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Serverless Offline",
"program": "${workspaceRoot}/node_modules/serverless/bin/serverless",
"args": [
"offline",
"--noTimeout",
"--dontPrintOutput",
"--stage=local",
"-P",
"4000",
"--aws-profile=#PROFILENAME#"
],
"sourceMaps": true,
"runtimeArgs": ["--lazy"],
"outFiles": ["${workspaceFolder}/.webpack/**/*.js"],
"protocol": "inspector",
"runtimeExecutable": "node",
"env": {
// Here we set some environment vars that should be set locally.
// They can and will overwrite the ones coming from your serverless.yml
},
"windows": {
"program": "${workspaceRoot}\\node_modules\\serverless\\bin\\serverless"
}
}
]
}
SET SLS_DEBUG=*
Then you can debug function as usual. If you don't have package.json you have to npm init and npm install as a 4th step.
You must install serverless in locally not globally to use the given launch.json
Upvotes: 0
Reputation: 7332
I think there is some misconception, pardon for switching from node.js context to python (the title is not specific to node so many folks will end up here anyway).
You CAN debug actual deployed AWS lambdas line-by-line. The approach involves running a debug server pydevd on the development machine and lambdas communicating with a debug-server over long-running TCP connection.
Is it supported by various IDEs, we use is with PyCharm Pro, so setup for it (hypothetically you should be able to setup VSCode similarly):
Debug configuration with Path mapping: right-top corner run/debug configuration dropdown -> Edit Configurations -> + (add new configuration) -> Python remote debug -> specify host name / port for your dev machine (which needs globally exposed: setup path forwarding on your router or use ngrok if previous option is not available). Make sure to setup path mappings, that is how your IDE can map the remote scripts to local sources.
pip install pydevd
. (For pycharm, you will need to install IDE-version specific custom distribution like: pip install pydevd-pycharm~=193.5233.109
)
Add the RemoteDebugSession
context manager abstraction(since debug session is over long-running tcp connection, its needs to be closed explicitly in your lambda otherwise lambda will timeout) like:
# from config import config
from logging import getLogger
logger = getLogger(__name__)
class RemoteDebugSession:
def __init__(self):
self.active = False
if not self.is_available():
logger.warning(f"Remote debugging is not available")
return
try:
# pydevd_pycharm exposes only settrace() from pydevd, import pydevd directly instead
# import pydevd_pycharm
import pydevd
self.pydevd = pydevd
except Exception as e:
logger.warning(f"Remote debugging is unavailable")
logger.warning(e)
self.pydevd = None
def __enter__(self):
if not self.is_available() or self.pydevd is None:
return
self.pydevd.settrace(config.REMOTE_DEBUG_HOST, port=config.REMOTE_DEBUG_PORT,
suspend=False,
stdoutToServer=True,
stderrToServer=True)
logger.warning("Starting remote dubugging session")
self.active = True
def __exit__(self, exc_type, exc_val, exc_tb):
if not self.active:
return
if exc_type or exc_val or exc_tb:
logger.warning(
f"Remote debugging on {config.REMOTE_DEBUG_HOST}:{config.REMOTE_DEBUG_HOST} failed")
logger.warning(exc_type)
logger.warning(exc_val)
logger.warning(exc_tb)
else:
logger.warning(f"Remote debugging on {config.REMOTE_DEBUG_HOST}:{config.REMOTE_DEBUG_HOST} closed")
self.pydevd.stoptrace()
@staticmethod
def is_available():
return hasattr(config, 'REMOTE_DEBUG_ENABLED') \
and hasattr(config, 'REMOTE_DEBUG_HOST') \
and hasattr(config, 'REMOTE_DEBUG_PORT') \
and config.REMOTE_DEBUG_ENABLED \
and config.REMOTE_DEBUG_HOST \
and config.REMOTE_DEBUG_PORT
You need to have config object with REMOTE_DEBUG_ENABLED, REMOTE_DEBUG_HOST, REMOTE_DEBUG_PORT set.
(pydevd.settrace is used with suspend=False
so the executing won't stop unless we set a breakpoint)
with RemoteDebugSession() as session:
# your code to examine
pass
In practice, when building web servers, this can be inside an individual API handler, which will allow you to debug multiple simultaneous incoming requests as other lambdas will block on connection.
Please REFRAIN from using this in production. Apart from security risk, remote evaluation can allow you to do all sort of nasty things.
Upvotes: 9
Reputation: 67
Rookout offers live debugging of NodeJS on AWS Lambda. This gives you breakpoints on the production function to allow traditional step-debugging. There are also lots of hacky solutions that effectively run your Lambda locally (eg lambda.local, serverless framework) but if you want to debug with true inputs, then debugging it in its true environment using Rookout is a good option.
Upvotes: 2
Reputation: 77
BothSAM Local and The Serverless framework provide tools to locally execute an AWS Lambda functions. In case you need to debug your function in the AWS environment, I suggest using Cloud9Cloud9 IDE for AWS Lambda debugging.
However, to debug invocation failures occurred in production, you could use something like Dashbird to detect and debug failures using logs, X-ray traces and other metadata.
Upvotes: 7
Reputation: 5367
You can now create tests within Lambda itself:
Choose Test at the top right of your Lambda function to bring up a screen that allows you to configure a new test that can be run. There are lots of example templates to choose from, including one for DynamoDB like you suggested:
Now choose your new test and click the Test button again. It will run immediately and you'll see console results on your screen, including logs and error messages.
Upvotes: 0
Reputation: 18764
You wont be able to do a step by step debug like you would on a regular program by attaching a debugger
.
As you mentioned you can use X-Ray and basically logging statements to figure out what went wrong.
As @ConfusedCoder pointed out there are ways in which you can run a lambda locally and debug it.
But also make sure you have enough logging in to ensure that you can try to figure out what went wrong, for future issues, using the logs as you would typically be looking at it after the actual execution happened.
Upvotes: 2
Reputation: 561
Lambda local can be used to test the lambda code in local machine.
Upvotes: 9