Debug Your Python Functions Locally
Debugging can quickly become a problem in serverless applications. As someone who benefits greatly from step-by-step debugging, I had some difficulty debugging Lambda functions efficiently. I’d get lost in the logs and found myself retrying endless permutations of parameters over and over again. Then I discovered the AWS Serverless Application Model (SAM). This Command-Line Interface (CLI) tool lets you debug your AWS Lambda functions the traditional way, providing step-by-step debugging at the per-line level.
With this new set of tools under my belt, I was able to successfully debug my Python Lambda functions locally. However, I still found myself struggling to find issues with code running in production configurations, that is, detecting and debugging failures in their native production environment. In a similar epiphany moment, we, as a team at Thundra, thought that there could be a better way of debugging AWS Lambda functions from within their native environment. That’s why we decided to build a real-time debugging tool for AWS Lambda functions. ServerlessDebugger lets you tie into Lambda code running in production and debug issues at their source.
Below, I’ll cover both methods of debugging Python Lambda functions. I’ll start with a walk-through of my previous method for debugging Python functions locally with AWS SAM CLI and then explore how I was able to move to the next level with Thundra's live debugging tool, ServerlessDebugger.
Debugging Lambda Functions Locally in VS Code
In order to debug these functions locally, you’ll need to install the AWS SAM CLI, which will receive most of the local testing commands we use. Let’s walk through the process step by step.
Step 1: Add a Visual Studio Code Launch Configuration
First, we need to add a launch configuration to VS Code so that we can attach the debugger to the simulated AWS runtime environment in which our functions will run. You can use the following launch configuration as a base for building your own:
Step 2: Install the Python Tools for Visual Studio Debug (PTVSD) Package
With our build configuration ready to go, we’ll next want to move on to the means of testing your application. If you haven’t already, install the PTVSD server into your Lambda application. You can do so by using the following command in the root directory of your Lambda application:
Step 3: Add PTVSD Code
Next, we need to invoke PTVSD so that we can connect our IDE to the running code we wish to test. To do this, add the following lines of code to the file that contains your Lambda handler:
Now that we’ve configured the debugger’s attach point, we need to add a breakpoint where we want PTVSD to stop. This should take place in your code after PTVSD is initialized:
Step 4: Invoke Your Function with the AWS SAM CLI
Putting everything together, we get the following command that we can use to invoke Lambda functions locally:
When you run this command, the AWS SAM CLI sets up the environment and waits for the VS Code debugger to be attached.
Step 5: Start Debugger and Connect to PTVSD
Now we’re ready to debug! Start the debugging tool in VS Code (F5 in macOS and Windows). VS Code will then attempt to connect to the port specified in the launch configuration file. Once the IDE has connected to the simulated PTVSD run, the function will continue executing and, eventually, hit our first breakpoint.
We now have a good old step-by-step debugger waiting for us at the breakpoint we specified! You can now step into function calls, step over them, watch variables, and more—just like when we debug regular applications!
Voila! The above displays that we successfully configured VS Code and AWS SAM CLI to allow you to locally debug your Python Lambda functions. There is, however, one important point remaining, namely that when you deploy your Lambda function, you need to make sure that you have removed or commented out the following lines in your application:
Live Debugging of Lambda with ServerlessDebugger
Once you’ve finished local debugging, you’ll want to see your function running on AWS hardware to let you see how your function actually operates with various third-party libraries and AWS services. While the approach we followed above allows you to make good progress as you develop, at some point you’ll need the ability to troubleshoot code in its production environment.
Luckily, ServerlessDebugger offers live debugging, a feature that lets you debug your functions in the AWS production environment. Below is a step-by-step guide for enabling live debugging of your AWS Lambda functions with ServerlessDebugger.
Step 1: Install the Thundra Lambda Layer for Your Function
The first step to debugging your functions online is to set up Thundra’s Lambda layer for your function. The Thundra Lambda layer includes your libraries and functionality, tying your application together with its dedicated Thundra dashboard. Modify your template.yml file to use the Thundra Lambda layer as detailed in our documentation.
Step 2: Define the AWS Lambda Debugger Environment Variable
Step 3: Connect Your IDE to the Debugging Environment
To connect your IDE to a running Lambda function, ServerlessDebugger uses the concept of named sessions. These named sessions tie your Lambda functions to your local IDE’s execution environment. You can manage this complexity effectively using the ServerlessDebugger's VSCode plugin. This gives you handy tools to modify your Thundra configuration, start a remote debugging session with or without a name, and more.
Step 4: Live Serverless Debugging Achieved
At this point, you have all of the tools you need to debug your production Python functions in a local development environment. The ServerlessDebugger VS Code plugin will automatically connect to the function secured with the debugger auth token you specify, and you’ll be able to troubleshoot your functions live from within VS Code as they execute on the AWS Lambda infrastructure.
Wrapping Up: Two Choices for Debugging Lambda
We’ve presented two different ways of debugging your Lambda functions: locally using PTVSD and remotely using the ServerlessDebugger. While PTVSD does a lot to allow us to troubleshoot Lambda functions in the process of execution, it will fall short if you need to work with any production resources or if you are attempting to troubleshoot a production-specific failure.
With the use of ServerlessDebugger, you can move past the shortcomings of a local-only debugging environment and get to the core of an issue quickly, efficiently, and in a way that a local environment simply cannot replicate.
Note: In the next episode of this article, we look into how to debug AWS Lambda Python functions.