On this page, you will learn how to manually instrument your lambda function. It's organized by runtime language. If you haven't already, create your free New Relic account below to start monitoring your data today.
To instrument your Go-language Lambda:
Download our Go agent package, and place it in the same directory as your function.
- Install the agent by running:bash$go get -u github.com/newrelic/go-agent/v3/newrelic
- Install the
nrlambda
integration by running:bash$go get -u github.com/newrelic/go-agent/v3/integrations/nrlambda
- Install the agent by running:
In your Lambda code, import our components, create an application, and update how you start your Lambda. See our instrumentation examples:
Optionally, add custom events that will be associated with your Lambda invocation by using the
RecordCustomEvent
API. For example:func handler(ctx context.Context) {if txn := newrelic.FromContext(ctx); nil != txn {txn.Application().RecordCustomEvent("MyEvent", map[string]interface{}{"zip": "zap",})}fmt.Println("hello world!")}Build and zip your Lambda function and upload it to AWS.
Here are suggestions for zipping and uploading the Lambda:
Build the binary for execution on Linux. This produces a binary file called
main
. You can use:bash$GOOS=linux go build -o mainZip the binary into a deployment package using:
bash$zip deployment.zip mainUpload the zip file to AWS using either the AWS Lambda console or the AWS CLI. Name the handler
main
(to match the name given during the binary build).
The following environment variables are not required for Lambda monitoring to function, but they are required if you want your Lambda functions to be included in distributed traces. To enable distributed tracing, set these environment variables in the AWS console:
NEW_RELIC_ACCOUNT_ID
. Your account ID.NEW_RELIC_TRUSTED_ACCOUNT_KEY.
This is also your account ID. If your account is a child account, this is the account ID for the root/parent account.
Optionally, to configure logging, see Go agent logging.
Invoke the Lambda at least once. This creates a CloudWatch log group, which must be present for the next step to work.
Our wrapper gathers data about the Lambda execution, generates a JSON message, and logs it to CloudWatch Logs. Next, you'll configure CloudWatch to send those logs to New Relic.
Monitoring for AWS Lambda in Java doesn't use our APM Java agent. Instead, it uses these two OpenTracing dependencies:
AWS Lambda OpenTracing Java SDK: OpenTracing instrumentation for AWS Lambda RequestHandler and RequestStreamHandler.
Our AWS Lambda OpenTracing Tracer: An OpenTracing Tracer implementation designed to monitor AWS Lambda. It generates spans, error events, transaction events, error traces, and provides distributed tracing support.
Tip
Supported OpenTracing Versions
- OpenTracing 0.31.0:
- Lambda Tracer: com.newrelic.opentracing:newrelic-java-lambda:1.1.1
- Lambda SDK: com.newrelic.opentracing:java-aws-lambda:1.0.0
- OpenTracing 0.32.0, 0.33.0:
- Lambda Tracer: com.newrelic.opentracing:newrelic-java-lambda:2.2.1
- Lambda SDK: com.newrelic.opentracing:java-aws-lambda:2.1.0
To instrument your Java Lambda:
- OpenTracing 0.31.0:
In your project’s
build.gradle
file, include our OpenTracing AWS Lambda Tracer and the AWS Lambda OpenTracing SDK dependencies:dependencies {compile("com.newrelic.opentracing:java-aws-lambda:2.1.0")compile("com.newrelic.opentracing:newrelic-java-lambda:2.2.1")compile("io.opentracing:opentracing-util:0.33.0")}Implement the AWS Lambda
RequestHandler
interface as shown in the Java Lambda example and override thedoHandleRequest
method.In the
doHandleRequest
method, call theLambdaTracing.instrument(...)
API to create a root span to trace the lambda function's execution. This is also where you will define your business logic for the lambda function.Register a
LambdaTracer.INSTANCE
as the OpenTracing Global tracer, as shown in the Java Lambda example.Create a ZIP deployment package and upload it to AWS Lambda. Or deploy it via other means.
In the AWS Lambda console, set the handler. For the example Java Lambda, the handler would be
com.handler.example.MyLambdaHandler::handleRequest
. BecausehandleRequest
is assumed, you could also usecom.handler.example.MyLambdaHandler
.The following AWS console environment variables are required if you want your Lambda function to be included in distributed tracing. This is recommended.
NEW_RELIC_ACCOUNT_ID
. Your account ID.NEW_RELIC_PRIMARY_APPLICATION_ID
. This is also your account ID.NEW_RELIC_TRUSTED_ACCOUNT_KEY
. This is also your account ID. If your account is a child account, this must be the account ID for the root/parent account.
Optional: In the Lambda console, enable debug logging by adding this environment variable:
NEW_RELIC_DEBUG
istrue
.Invoke the Lambda at least once. This creates a CloudWatch log group, which must be present for the next step to work.
Our wrapper gathers data about the Lambda execution, generates a JSON message, and logs it to CloudWatch Logs. Next, you'll configure CloudWatch to send those logs to New Relic.
Please see the AWS Lambda distributed tracing example for a complete project that illustrates common use cases such as:
- Distributed tracing between Lambda functions
- Manual span creation (aka custom instrumentation)
- Tracing external calls
- Adding custom attributes (aka Tags) to spans
Our monitoring of .NET Core-based AWS Lambda functions doesn't use our standard .NET Core APM agent. Instead, it uses a NuGet package.
To instrument your .NET Core Lambda:
In your Lambda Functions project, install the
NewRelic.OpenTracing.AmazonLambda.Tracer
NuGet package.Note:
NewRelic.OpenTracing.AmazonLambda.Tracer
depends on version 1.2.0+ ofAmazon.Lambda.APIGatewayEvent
NuGet package. If the environment already uses a lower version ofAmazon.Lambda.APIGatewayEvent
, the New Relic package may produce errors such asSystem.MissingMethodException
.Import the NuGet package and OpenTracing utils:
using OpenTracing.Util;using NewRelic.OpenTracing.AmazonLambda;Instrument your function, as shown in this example:
public class Function{static Function(){// Register The NewRelic Lambda Tracer InstanceGlobalTracer.Register(NewRelic.OpenTracing.AmazonLambda.LambdaTracer.Instance);}public object FunctionWrapper(ILambdaContext context){// Instantiate NewRelic TracingWrapper and pass your FunctionHandler as// an argumentreturn new TracingRequestHandler().LambdaWrapper(FunctionHandler, context);}/// <summary>/// A simple function that takes a string and does a ToUpper/// </summary>/// <param name="input"></param>/// <param name="context"></param>/// <returns></returns>public object FunctionHandler(ILambdaContext context){ ... }}Tip
The arguments passed to
FunctionWrapper
must match the signature ofFunctionHandler
.If your handler function returns a Task, the Lambda wrapper will block on the return task until it completes, so that it can measure the duration and capture exceptions, if any are present. In addition, you may also inherit from the
APIGatewayProxyFunction
.For an example, see below:
public async Task<int> FunctionHandlerAsync(ILambdaContext lambdaContext){return await new TracingRequestHandler().LambdaWrapper(ActualFunctionHandlerAsync, lambdaContext);}public async Task<APIGatewayProxyResponse> ActualFunctionHandlerAsync(ILambdaContextlambdaContext){// Function can make other async operations here...}public class LambdaFunction : APIGatewayProxyFunction{static LambdaFunction(){// Register The NewRelic Lambda Tracer InstanceOpenTracing.Util.GlobalTracer.Register(NewRelic.OpenTracing.AmazonLambda.LambdaTracer.Instance);}public override Task<APIGatewayProxyResponse> FunctionHandlerAsync(APIGatewayProxyRequest request, ILambdaContext lambdaContext){Task<APIGatewayProxyResponse> task = new TracingRequestHandler().LambdaWrapper(ActualFunctionHandlerAsync, request, lambdaContext);return task;}public Task<APIGatewayProxyResponse> ActualFunctionHandlerAsync(APIGatewayProxyRequest request, ILambdaContext lambdaContext){return base.FunctionHandlerAsync(request, lambdaContext);}}Optional for SQS and SNS: Starting in version 1.0 of our .NET Lambda Tracer, distributed tracing support has been added for SQS and SNS. To enable distributed tracing for SQS or SNS you will need to complete the items in this step as well as setup the environment variables in the step that follows this one.
Important
Enabling distributed tracing support for SQS and SNS will disable automatic instrumentation for both of SQS and SNS and require the use of these wrappers to instrument them.
- Set the
NEW_RELIC_USE_DT_WRAPPER
environment variable totrue
. - To instrument SQS and SNS calls you will need to use the provided wrappers.
The SQS wrapper supports wrapping the following methods:
Amazon.SQS.AmazonSQSClient.SendMessageAsync(...)
Amazon.SQS.AmazonSQSClient.SendMessageBatchAsync(...)
Examples
// SQS ClientAmazonSQSClient client = new AmazonSQSClient("AWS_SECRET_ACCESS_KEY", AWS_REGION);// SendMessageRequestSendMessageRequest sendRequest = new SendMessageRequest("QUEUE_URI_STRING", "An SQS Message");Task<SendMessageResponse> responseOne = SQSWrapper.WrapRequest(client.SendMessageAsync, sendRequest);// String-basedTask<SendMessageResponse> responseTwo = SQSWrapper.WrapRequest(client.SendMessageAsync, "QUEUE_URI_STRING", "Another SQS Message");// SendMessageBatchRequestList<SendMessageBatchRequestEntry> batchEntries = new List<SendMessageBatchRequestEntry>();batchEntries.Add(new SendMessageBatchRequestEntry("id1", "First SQS Message"));batchEntries.Add(new SendMessageBatchRequestEntry("id2", "Second SQS Message"));batchEntries.Add(new SendMessageBatchRequestEntry("id3", "Third SQS Message"));SendMessageBatchRequest sendBatchRequest = new SendMessageBatchRequest(QUEUE_URI, batchEntries);Task<SendMessageBatchResponse> response = SQSWrapper.WrapRequest(client.SendMessageBatchAsync, sendBatchRequest);// SendMessageBatchRequestEntry ListList<SendMessageBatchRequestEntry> moreBatchEntries = new List<SendMessageBatchRequestEntry>();batchEntries.Add(new SendMessageBatchRequestEntry("id4", "Fourth SQS Message"));batchEntries.Add(new SendMessageBatchRequestEntry("id5", "Fifth SQS Message"));batchEntries.Add(new SendMessageBatchRequestEntry("id6", "Sixth SQS Message"));Task<SendMessageBatchResponse> response = SQSWrapper.WrapRequest(client.SendMessageBatchAsync, moreBatchEntries);
The SNS wrapper supports wrapping the following methods:
Amazon.SimpleNotificationService.AmazonSimpleNotificationServiceClient.PublishAsync(...)
Examples
// SNS ClientAmazonSimpleNotificationServiceClient client = new Amazon.SimpleNotificationService.AmazonSimpleNotificationServiceClient("AWS_SECRET_ACCESS_KEY", AWS_REGION);// PublishRequest - Phone NumberPublishRequest phonePublishRequest = new PublishRequest();phonePublishRequest.PhoneNumber = +1XXX5555100;phonePublishRequest.Message = "An SNS Message for phones";Task<PublishResponse> phoneResponse = SNSWrapper.WrapRequest(client.PublishAsync, phonePublishRequest);// PublishRequest - ARNPublishRequest publishRequest = new PublishRequest("TOPIC_ARN", "An SNS Message");Task<PublishResponse> publishResponse = SNSWrapper.WrapRequest(client.PublishAsync, publishRequest);// String-based without subjectTask<PublishResponse> responseOne = SNSWrapper.WrapRequest(client.PublishAsync, "TOPIC_ARN", "Another SNS Message");// String-based with subjectTask<PublishResponse> responseTwo = SNSWrapper.WrapRequest(client.PublishAsync, "TOPIC_ARN", "Yet Another SNS Message", "A Subject");
- Set the
The following environment variables are not required for Lambda monitoring to function but they are required if you want your Lambda functions to be included in distributed traces. To enable distributed tracing, set these environment variables in the AWS Lambda console:
NEW_RELIC_ACCOUNT_ID
: The account ID the Lambda is reporting to.NEW_RELIC_TRUSTED_ACCOUNT_KEY
: This is also the account ID. If your account is a child account, this needs to be the account ID for the root/parent account.
Ensure that the wrapper function (
FunctionWrapper
in above example) is set up as the function handler.Invoke the Lambda at least once. This creates a CloudWatch log group, which must be present for the next step to work.
Our wrapper gathers data about the Lambda execution, generates a JSON message, and logs it to CloudWatch Logs. Next you'll configure CloudWatch to send those logs to New Relic.
To instrument your Node.js Lambda:
Download our Node.js agent package and place it in the same directory as your function, ensuring the agent is installed as a dependency in the
node_modules
directory. Use the Node Package Manager:bash$npm install newrelic --saveIn your Lambda code, require the agent module at the top of the file, and wrap the handler function. For example:
const newrelic = require('newrelic');// Other module loads go under the require statement abovemodule.exports.handler = newrelic.setLambdaHandler((event, context, callback) => {// This is your handler function codeconsole.log('Lambda executed');callback();});Optional: You can also add custom events to your Lambda using the
recordCustomEvent
API. For example:module.exports.handler = newrelic.setLambdaHandler((event, context, callback) => {newrelic.recordCustomEvent('MyEventType', { foo: 'bar' });console.log('Lambda executed');callback();});Zip your Lambda function and the Node.js agent folder together. Requirements and recommendations:
- The New Relic files outside the New Relic agent folder don't need to be included.
- If your Lambda function file name is, for example,
lambda_function.node
, we recommend naming your zip filelambda_function.zip
. Do not use a tarball. - Your Lambda and its associated modules must all be in the zip file's root directory. This means that if you zip a folder that contains the files, it won't work.
Upload the zipped file to your AWS Lambda account.
In the AWS console, set these environment variables:
NEW_RELIC_NO_CONFIG_FILE
. Set totrue
if not using a configuration file.NEW_RELIC_APP_NAME
: Your application name.NEW_RELIC_ACCOUNT_ID
. Your account ID.NEW_RELIC_TRUSTED_ACCOUNT_KEY
. This is also your account ID. If your account is a child account, this needs to be the account ID for the root/parent account.
Optional: To run the agent in serverless mode outside of AWS in a local environment, set the environment variable
NEW_RELIC_SERVERLESS_MODE_ENABLED
totrue
. (When executing this in an AWS Lambda environment, the agent will automatically run in serverless mode. Do not use this variable if you're running in AWS.)Optional: To enable logging in serverless mode, set these environment variables:
- Set
NEW_RELIC_LOG_ENABLED
totrue
. - Set
NEW_RELIC_LOG
tostdout
for output to CloudWatch, or set to any writeable file location. NEW_RELIC_LOG_LEVEL
is set toinfo
by default, and it's only used when sending function logs in your Lamba. See other log levels.
- Set
Invoke the Lambda at least once. This creates a CloudWatch log group, which must be present for the next step to work.
Our wrapper gathers data about the Lambda execution, generates a JSON message, and logs it to CloudWatch Logs. Next you'll configure CloudWatch to send those logs to New Relic.
Read more on how to send function logs with Lambda.
To instrument your Python Lambda:
Download our Python agent package and place it in the same directory as your function. To do this, use pip:
bash$pip install -t . newrelicImportant
If you use Homebrew, you may get this error:
DistutilsOptionError: must supply either home or prefix/exec-prefix -- not both
. For details, see the Homebrew GitHub post.In your Lambda code, import the Python agent module and decorate the handler function using the New Relic decorator. The New Relic package must be imported first in your code. Here's an example:
import newrelic.agentnewrelic.agent.initialize()@newrelic.agent.lambda_handler()def handler(event, context):...Optional: You can also add custom events to your Lambda using the
record_custom_event
API. Here's an example:@newrelic.agent.lambda_handler()def handler(event, context):newrelic.agent.record_custom_event('CustomEvent', {'foo': 'bar'})...Zip your
lambda_function.py
andnewrelic/
folder together using these guidelines:- The New Relic files outside the
newrelic/
folder don't need to be included. - If your Lambda function file name is, for example,
lambda_function.py
, name your zip filelambda_function.zip
. Do not use a tarball. - Your Lambda and its associated modules must all be in the zip file's root directory. This means that if you zip a folder that contains the files, it won't work.
- The New Relic files outside the
Upload the zipped file to your AWS Lambda account.
In the AWS console, set this environment variable:
NEW_RELIC_SERVERLESS_MODE_ENABLED
. Set totrue
The following environment variables are not required for Lambda monitoring to function but they are required if you want your Lambda functions to be included in distributed traces. To enable distributed tracing, set these environment variables in the AWS console:
NEW_RELIC_DISTRIBUTED_TRACING_ENABLED
. Set to true.NEW_RELIC_ACCOUNT_ID
. Your account ID.NEW_RELIC_TRUSTED_ACCOUNT_KEY.
This is also your account ID. If your account is a child account, this needs to be the account ID for the root/parent account.
Optional: To configure logging, use the
NEW_RELIC_LOG
andNEW_RELIC_LOG_LEVEL
environment variables in the AWS Console.Invoke the Lambda at least once. This creates a CloudWatch log group, which must be present for the next step to work.
The New Relic decorator gathers data about the Lambda execution, generates a JSON message, and logs it to CloudWatch Logs. Next, configure CloudWatch to send those logs to New Relic.