Tracking AWS Lambda errors with Sentry (and CloudFormation)

I enjoy working with Sentry for error tracking: I have a real-time overview of errors, I set up various alerts, and I use it in both backend and frontend systems. Now, how to setup Sentry for AWS Lambda that is provisioned by AWS CloudFormation?

There are currently two ways to do it: wrapping up the Lambda handler or using AWS Lambda layers. I focus on the Lambda handler here.

Step 1: Wrapping up handler

Following the Sentry docs on integrating with AWS Lambda, this step was straightforward. Here's an example of a wrapped Node handler:

  1. Install Sentry lib:

    npm install --save @sentry/serverless
  2. Wrap the Lambda handler:

    const Sentry = require("@sentry/serverless")
      dsn: "<Your Sentry DSN>",
      // ...
    exports.handler = Sentry.AWSLambda.wrapHandler(async (event, context) => {
      // Your handler code

In the current version of the library (6.2.3), I had to tweak the setup a bit to make it work with WebPack and Typescript.

Step 2: Setting up CloudFormation

Now, Sentry supports monitoring errors per environment, such as dev, acceptance, or production. I like that because I have more control over errors in different environments. The environment is set up in the Lambda itself:

  dsn: "<Your Sentry DSN>",
  environemnt: "acceptnace"  # <--- here we supply the lambda environment

Now, how to supply the lambda environment using CloudFormation? It turns out, this can be achieved with parameters.

(In the steps below, I also use AWS Parameter Store to fetch the Sentry DSN instead of having the DSN hardcoded in the Sentry init):

  1. Setup the Cloudformation template: add an environment parameter and Sentry DSN parameter

    # content of template.yml
    AWSTemplateFormatVersion: '2010-09-09'
    Transform: AWS::Serverless-2016-10-31
      # here we define that the CloudFormation stack accepts environment parameter
    	Type: String
    	  - dev
    	  - acc
    	  - prod
      # here we fetch the sentry URL from SSM Parameter store
    	Type: AWS::SSM::Parameter::Value<String>
    	Default: '/<your-path-to-sentry-dsn-ssm-parameter>'
    	Type: AWS::Serverless::Function
    		# here we supply sentry dsn & lambda environment to lambda
    		  SENTRY_DSN: !Ref SentryDSN
    		  LAMBDA_ENVIRONMENT: !Ref LambdaEnvironment
    		# we need to allow reads from SSM parameter store
    	   - SSMParameterReadPolicy:
    		 ParameterName: '/<your-path-to-sentry-dsn-ssm-parameter>'
    	#CodeUri, Events, etc...
  2. In Lambda, read from the env vars instead:

      dsn: process.env.SENTRY_DSN,
      environemnt: process.env.LAMBDA_ENVIRONMENT,
  3. When deploying the CloudFormation stack in a CI pipeline, supply --parameter-overrides argument to aws cloudformation deploy:

    aws cloudformation deploy --template-file template.yml  \
    	--parameter-overrides "LAMBDA_ENVIRONMENT=acc" \
    	# ... other args & options ...

This should be it 🎉.

Sidenote on AWS Lambda logs & CLI

Speaking of errors, it turns out one can tail aws logs via a CLI using aws logs. Plus, there's no need to specify the log stream, which is handy:

#  print all log groups
aws logs describe-log-groups

# tail logs for lambda example-lambda since 1 day ago
aws logs tail /aws/lambda/example-lambda --since 1d --follow |

I like to combine aws logs with grep context lines to search for errors with the surrounding context:

# show all ERROR log messages. For each ERROR msg, show 10 preceding messages
aws logs tail /aws/lambda/example-name --since 1d | grep -B 10 'ERROR'

Would you like to connect? Subscribe via email or RSS , or follow me on Twitter!