Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to debug a aws lambda function?

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?

like image 423
justcode Avatar asked Apr 23 '18 17:04

justcode


People also ask

How do you debug a Lambda function?

When you locally invoke a Lambda function in debug mode within the AWS SAM CLI, you can then attach a debugger to it. With the debugger, you can step through your code line by line, see the values of various variables, and fix issues the same way you would for any other application.

Can we debug Lambda function?

You can use AWS SAM with a variety of AWS toolkits and debuggers to test and debug your serverless applications locally. For example, you can perform local step-through debugging of your Lambda functions by setting breakpoints, inspecting variables, and executing function code one line at a time.

How do I debug AWS Lambda remotely?

With Lambda open in AWS Explorer, right-click the name of the function, and then choose Run '[Remote]'. Complete the Edit configuration (remote function settings) dialog box if it's displayed, and then choose Run or Debug. Results are displayed in the Run or Debug tool window.


2 Answers

Lambda local can be used to test the lambda code in local machine.

like image 67
cerberus Avatar answered Oct 03 '22 05:10

cerberus


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):

  1. 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.

  2. pip install pydevd. (For pycharm, you will need to install IDE-version specific custom distribution like: pip install pydevd-pycharm~=193.5233.109)

  3. 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)

  1. Wrap your feature of interest with it like:
 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.

like image 27
ambientlight Avatar answered Oct 03 '22 04:10

ambientlight