Quickly Debug Your AWS Lambda Functions

In this article, we’ll be looking into four different methods of how to debug AWS Lambda functions faster.

Great writers use metaphors to get their point across, so let me give that a try real quick.

Bugs are nasty little pests. It’s hard to get rid of them, but apart from just spraying poison everywhere, there are only a few options left. One of those options is using a natural predator to get rid of those bugs, a predator like birds.

So birds can help you get rid of bugs, and I work for a company called Dashbird that helps developers debug their AWS Lambda applications.

See what I did there? Pests\bugs ⇔ birds\Dashbirds?

Classifying Types of Errors

Let’s first begin by first classifying the types of errors you would encounter so we can prioritize what to monitor and debug. If you know the types already, feel free to skip ahead to where we debug a Lambda function. 

  • Implicit/Fatal: The process execution stops and you get a core dump (or you perform log analysis).
  • Explicit/Fatal: Process stops and gives you an error code.
  • Implicit/Non-Fatal: Process continues to run, without actually doing what it is supposed to do. Or does things inefficiently.
  • Explicit/Non-Fatal: Process gives a warning message, and continues running after that.

The errors that belong to the explicit category are easier to debug, regardless of whether or not they are fatal. The error message itself gives a pretty clear indication of the exact cause of the problem which can then be dealt with, instantaneously.

The implicit fatal errors are a bit harder to debug. We know something is wrong because the process stopped unexpectedly. But you can get to the root cause of the problem by inspecting the snapshot of memory at the time of the crash. It is popularly known as the core-dump and is common while debugging low-level languages like C. Recently, similar features for Node.js and Go have been introduced as well.

The nastiest of bugs are the implicit non-fatal ones. This might mean that your function either runs successfully performing the wrong action, or it is just inefficient in terms of resources management and you don’t know which one it is.

This could occur if the developer didn’t understand the end goal of a function, or if the wrong library or data structure was used for the purpose. These bugs fly under the radar for very long periods of time. They often hurt your cloud bills and leave your customers unhappy because your apps are too slow. These bugs are often not reproducible outside the production environment and they need to be dealt with swiftly. Most security vulnerabilities also fall under this category.

Now that we know what type of errors to priortize, let’s focus on using AWS Lambda and debug with Dashbird.

Main Reasons for Using AWS Lambda Functions

One of the main AWS Lambda perks is that, as AWS claim, “You can forget all about the project’s infrastructure and focus solely on launching apps in the cloud while you’ll be able to perform integrations with other Amazon services.” Scalability and the low cost of using the AWS computing resources are other perks that come along.

anatomy of a functionAnatomy of a Lambda function – AWS re:Invent 2017

All you need to do is to write your function, connect it to an event, deploy it, and AWS will take care of the rest. The Lambda function will process thousands of requests every hour on AWS with no need for your effort whatsoever.

But what happens when a Lambda function fails?

How to Debug AWS Lambda Functions?

When talking about the debugging process on AWS Lambda functions, four methods are most commonly used. These methods can be grouped into two categories. The first one is offline debugging, and the second one logging.

Debugging Lambda Functions Offline

Offline debugging allows you to work locally in case of a standard development process.

The Serverless Offline library is great for debugging your application while it’s still in development. It acts very similar to AWS, giving you access to various services like SQS, SNS, S3, etc., only, instead of the request hitting the live services, it goes to a local emulated service.

Logging Lambda Functions Online

Suppose you have a live service or have a dev/staging environment or multiple developers working on the same project at once. In that case, you’ll need to start looking at live debugging services. While there are tons of tools to debug monolith applications, for serverless specifically, there are only a few tools for debugging, some better than others.

But when you deploy your Lambda function to real infrastructure, logging might be the only debug method left. Logging can be done in three ways.

  1. First, log directly to AWS CloudWatch, by simply writing to standard out. This is probably the most popular method because it’s easy to set up. The downsides of CloudWatch are that all the logs are grouped, and it can take a lot of time to figure out what’s wrong when you have many moving parts in your app. Nevertheless, it’s probably the best option if you are just starting with AWS Lambda.
  2. The second way is to write your own logging tool with AWS services like Kinesis. In this process, the need for manually creating these tools will take developers a lot of time, which further means it’ll cost more since additional Amazon infrastructure will be used. But at first, this process seems quite faster.
  3. The third way is the use of third-party logging services. They don’t have the downsides of using CloudWatch but also don’t require you to waste development time.

Dashbird is the only tool entirely dedicated to monitoring and debugging AWS Lambda applications and serverless systems, and the main reason our users love the service is its simplicity. With just a few clicks you can connect your AWS account, no code changes, and start discovering and troubleshooting unknown and known errors from general statistics of your microservices to individual function execution profiles.

AWS Lambda monitoring

Debugging AWS Lambda Functions with Dashbird

Dashbird is an excellent choice since it was built especially for serverless developers, and it’s able to detect quickly any sorts of failures. Dashbird offers quite a lot of features for effective debugging like:

  • Error Views necessary in showing and discovering the point of failure that gives developers insight into what went wrong.
  • Log Search allows you to search through Lambda logs, which means you’ll be able to find relevant invocations.
  • Function View allows you to look closer into any function that seems to misbehave and thoroughly work on it.
  • Inventory and Resource views allows developers to perform a real-time observation of a function’s activity.
  • Tracing gives you an incredible and compelling insight into what your invocations are doing and how they’re interconnected.

debugging dashboard with x ray

Debugging an Example Lambda Function

Let’s try to debug an example function. We can create one with the AWS Lambda web console. I’ll assume that you know how to do this and just give you the example code here:

exports.handler = async (event, context) => {
  console.log("Logging!");
  
  const x = event.a.b;
};

Two types of logs will be produced by this function. First the call to the console.log function then the access of an undefined event property.

If you open up Dashbird, the first thing you will see is the main dashboard. This error will be in plain sight.

dashbird dashboard showing errors

Cannot read property ‘b’ of undefined” — a well-known JavaScript error message. When you click on it, you get the event view with more details of the error.

error detail with stack trace

Dashbird’s error details will show you when the error first happened, when it last happened, where it happened and how severe it actually is.

It even gives you a stack trace, which helps to debug the error before the next deployment.

But where did the call to console.log end up? If you go to Inventory and click on your Lambda function in the list that opens you can choose from the last invocations of that function. My function is called extractRecords so that’s what I’ll search for.

invocation logs

If I click on the last invocation, the logs of that invocation will open and I’ll see the log call and the error.

debugging and tracing details

Depending on the number of logs you write in your function, it can become hard to find the error, that’s why I’d recommend using the error details when debugging.

Summary

AWS Lambda functions are working in an isolated remote environment, which complicates debugging more and more. While your code is in the development phase, it’s still crucial to go through frameworks (think Serverless Application Model) to monitor and debug your code on your machine.

When you finally deploy your function to the cloud, different methods are required to get the insights you need. If you think CloudWatch is too clunky and you want to see what’s happening at one glance, give Dashbird a try. It’s built from the ground up to monitor serverless applications and removes many obstacles you would find when building your own logging service.


Further reading:

Using Observability to scale AWS Lambda [webinar]

How to save hundreds of hours on AWS Lambda debugging?

4 tips for tuning AWS Lambda for production

Performance monitoring for AWS Lambda

Grouping AWS Lambda functions into project views

Read our blog

Daniel Grzelak joins Dashbird’s advisory board

Dashbird is thrilled to welcome legendary security executive, Daniel Grzelak, to its advisory board. Daniel is currently serving as the Security Chief of Staff at Atlassian.

How to check NFT supply with AWS Lambda?

How can serverless technology be used in tandem with blockchains? Find out how we built a Lambda function to monitor NFT supplies.

Python Error Handling in AWS Lambda

Best Practices and need-to-knows for error handling in Python AWS Lambdas.

More articles

Made by developers for developers

Dashbird was born out of our own need for an enhanced serverless debugging and monitoring tool, and we take pride in being developers.

What our customers say

Dashbird gives us a simple and easy to use tool to have peace of mind and know that all of our Serverless functions are running correctly. We are instantly aware now if there’s a problem. We love the fact that we have enough information in the Slack notification itself to take appropriate action immediately and know exactly where the issue occurred.

Thanks to Dashbird the time to discover the occurrence of an issue reduced from 2-4 hours to a matter of seconds or minutes. It also means that hundreds of dollars are saved every month.

Great onboarding: it takes just a couple of minutes to connect an AWS account to an organization in Dashbird. The UI is clean and gives a good overview of what is happening with the Lambdas and API Gateways in the account.

I mean, it is just extremely time-saving. It’s so efficient! I don’t think it’s an exaggeration or dramatic to say that Dashbird has been a lifesaver for us.

Dashbird provides an easier interface to monitor and debug problems with our Lambdas. Relevant logs are simple to find and view. Dashbird’s support has been good, and they take product suggestions with grace.

Great UI. Easy to navigate through CloudWatch logs. Simple setup.

Dashbird helped us refine the size of our Lambdas, resulting in significantly reduced costs. We have Dashbird alert us in seconds via email when any of our functions behaves abnormally. Their app immediately makes the cause and severity of errors obvious.