Skip to main content

Monitoring Your App in Prod

Once your app has been deployed to production, it's useful to be able to monitor your Lambda functions. There are a few different services that you can use for this. We'll look at them below.

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
npm install --save-dev datadog-cdk-constructs

# Yarn
yarn add --dev datadog-cdk-constructs

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

import { Datadog } from "datadog-cdk-constructs";

const datadog = new Datadog(this, "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(this.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.

import { LayerVersion } from "@aws-cdk/aws-lambda";

const sentry = LayerVersion.fromLayerVersionArn(
this,
"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.

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.

import Sentry from "@sentry/serverless";

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

For more details, check out the Sentry docs.

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 epsagon

And wrap your Lambda functions with their tracing wrapper.

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

export { handler };

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.

import * as cdk from "@aws-cdk/core";

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.

import * as cdk from "@aws-cdk/core";

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

import { LayerVersion } from "@aws-cdk/aws-lambda";

const thundraLayer = LayerVersion.fromLayerVersionArn(this, "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.

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

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

In your App's stacks/index.js, you'll also need to tell the bundler to ignore the following packages that cause a conflict with Thundra's layer.

if (!app.local) {
app.setDefaultFunctionProps({
bundle: {
externalModules: [
"fsevents",
"jest",
"jest-runner",
"jest-config",
"jest-resolve",
"jest-pnp-resolver",
"jest-environment-node",
"jest-environment-jsdom",
],
},
});
}

For more details, check out the Thundra docs.