Skip to main content

Monitoring

SST integrates with all the major observability providers to help you monitor your apps in production.

Once your app has been deployed to production, there are a few different options on how to monitor your Lambda functions. Let's look at them here.


Datadog

Datadog offers an End-to-end Serverless Monitoring solution that works with Lambda functions. The best way to integrate is by using the CDK construct they provide.

Start by adding it to your project.

npm install --save-dev datadog-cdk-constructs

Next, you'll need to import it into a stack. Add pass in the functions you want monitored.

stacks/Foo.js
import { Datadog } from "datadog-cdk-constructs";

const datadog = new Datadog(stack, "Datadog", {
nodeLayerVersion: 65,
extensionLayerVersion: 13,
apiKey: "<DATADOG_API_KEY>",
});

datadog.addLambdaFunctions([myfunc]);

To monitor all the functions in a stack, you can use the Stack construct's getAllFunctions method and do the following at the bottom of your stack definition.

datadog.addLambdaFunctions(stack.getAllFunctions());

For more details, check out the Datadog docs.


Sentry

Sentry offers Serverless Error Monitoring for your Lambda functions. Integration is done through a Lambda Layer.

Head over to the Layer that Sentry provides, select your region and copy the layer ARN.

Then add the Layer to your stack.

stacks/Foo.js
import { LayerVersion } from "aws-cdk-lib/aws-lambda";

const sentry = LayerVersion.fromLayerVersionArn(
stack,
"SentryLayer",
`arn:aws:lambda:${scope.region}:943013980633:layer:SentryNodeServerlessSDK:34`
);

You can then set it for all the functions in your stack using the addDefaultFunctionLayers and addDefaultFunctionEnv. Note we only want to enable this when the function is deployed, not when using Live Lambda Dev.

stacks/Foo.js
if (!scope.local) {
stack.addDefaultFunctionLayers([layer]);
stack.addDefaultFunctionEnv({
SENTRY_DSN: "<SENTRY_DSN>",
NODE_OPTIONS: "-r @sentry/serverless/dist/awslambda-auto",
});
}

Sentry also offers performance monitoring for serverless. To enable, add the SENTRY_TRACES_SAMPLE_RATE environment variable.

stack.addDefaultFunctionEnv({
SENTRY_DSN: "<SENTRY_DSN>",
SENTRY_TRACES_SAMPLE_RATE: "1.0",
NODE_OPTIONS: "-r @sentry/serverless/dist/awslambda-auto",
});

This can be tuned between the values of 0 and 1. Where 0 means that no performance related information is sent, and 1 means that information for all the invocations are sent. This should be tuned based on the volume of invocations and the amount of transactions available in your Sentry account. A value of 0.5 should work for most projects.

You also need to wrap your function handlers.

services/functions/foo.js
import * as Sentry from "@sentry/serverless";

export const handler = Sentry.AWSLambda.wrapHandler(async (event) => {
// ...
});

For more details, check out the Sentry docs.


Lumigo

Lumigo offers a Serverless Monitoring and Debugging Platform.

To get started, sign up for an account. Then follow their wizard to deploy their stack in your AWS production account.

Then to enable Lambda monitoring for a function, add a lumigo:auto-trace tag and set it to true.

stacks/Foo.js
import * as cdk from "aws-cdk-lib";

cdk.Tags.of(myfunc).add("lumigo:auto-trace", "true");

To monitor all the functions in a stack, you can use the Stack construct's getAllFunctions method and do the following at the bottom of your stack definition.

stacks/Foo.js
import * as cdk from "aws-cdk-lib";

stack
.getAllFunctions()
.forEach((fn) => cdk.Tags.of(fn).add("lumigo:auto-trace", "true"));

For more details, check out the Lumigo docs on auto-tracing.


Thundra

Thundra offers Thundra APM - Application Performance Monitoring for Serverless and Containers.

To get started, sign up for an account. Then follow the steps in the quick start guide to deploy their stack into the AWS account you wish to monitor.

To enable Lambda monitoring, you'll need to add a layer to the functions you want to monitor. To figure out the layer ARN for the latest version, check the badge here.

With the layer ARN, you can use the layer construct in your CDK code.

stacks/Foo.js
import { LayerVersion } from "aws-cdk-lib/aws-lambda";

const thundraLayer = LayerVersion.fromLayerVersionArn(
stack,
"ThundraLayer",
"<ARN>"
);

You can then set it for all the functions in your stack using the addDefaultFunctionLayers and addDefaultFunctionEnv. Note we only want to enable this when the function is deployed, not in Live Lambda Dev as the layer will prevent the debugger from connecting.

stacks/Foo.js
if (!scope.local) {
const thundraAWSAccountNo = 269863060030;
const thundraNodeLayerVersion = 94; // Latest version at time of writing
const thundraLayer = LayerVersion.fromLayerVersionArn(
stack,
"ThundraLayer",
`arn:aws:lambda:${scope.region}:${thundraAWSAccountNo}:layer:thundra-lambda-node-layer:${thundraNodeLayerVersion}`
);
stack.addDefaultFunctionLayers([thundraLayer]);

stack.addDefaultFunctionEnv({
THUNDRA_APIKEY: process.env.THUNDRA_API_KEY,
NODE_OPTIONS: "-r @thundra/core/dist/bootstrap/lambda",
});
}

For more details, check out the Thundra docs.


Time Travel Debugging

Thudra also offers a feature called Time Travel Debugging (TTD) that makes it possible to travel back in time to previous states of your application by getting a snapshot of when each line is executed. You can step over each line of the code and track the values of the variables captured during execution.

To enable TTD in your SST app, you'll need to modify the esbuild config. Check out the Thundra docs on this.


New Relic

New Relic offers New Relic Serverless for AWS Lambda.

To get started, follow the steps in the documentation.

To enable Lambda monitoring, you'll need to add a layer to the functions you want to monitor. To figure out the layer ARN for the latest version, check the available layers per region here.

With the layer ARN, you can use the layer construct in your CDK code. To ensure the Lambda function is instrumented correctly, the function handler must be set to the handler provided by the New Relic layer. Note we only want to enable this when the function is deployed, not in Live Lambda Dev as the layer will prevent the debugger from connecting.

stacks/Foo.js
import { CfnFunction, LayerVersion } from "aws-cdk-lib/aws-lambda";

const newRelicLayer = LayerVersion.fromLayerVersionArn(
stack,
"NewRelicLayer",
"<ARN>>"
);

// Configure New Relic handler wrapper if not in local mode
if (!scope.local) {
this.getAllFunctions().map((fn) => {
const cfnFunction = fn.node.defaultChild as CfnFunction;

if (cfnFunction.handler) {
fn.addEnvironment("NEW_RELIC_LAMBDA_HANDLER", cfnFunction.handler);
}

cfnFunction.handler = "newrelic-lambda-wrapper.handler";
});
}

Epsagon

caution

Epsagon is undergoing some changes after the acquisition by Cisco. We recommend using one of the other monitoring services.

Epsagon is an end-to-end Application Monitoring Service and can monitor the full lifecycle of your serverless requests.

The Epsagon docs on using a Lambda Layer are incorrect. You'll need to install the Epsagon agent for your Lambda functions.

npm install --save-dev epsagon

And wrap your Lambda functions with their tracing wrapper.

services/functions/foo.js
const handler = epsagon.lambdaWrapper(function (event, context) {
// Lambda code
});

export { handler };