Enable New Relic monitoring of AWS Lambda

New Relic monitoring for AWS Lambda offers in-depth performance monitoring for your Lambda functions. This document explains how to enable this feature and get started using it.

Use of this feature may result in Amazon Web Services charges. For more information, see Requirements.

How Lambda monitoring works

Before going through the enable procedures, it may help you to understand how data flows from your Lambda functions to New Relic:

New Relic monitoring for AWS Lambda architecture - diagram
Diagram showing how data flows from a Lambda function to New Relic.

When New Relic's Lambda monitoring is enabled, this is how data moves from your Lambda function to New Relic:

  1. The Lambda function is instrumented with our code. When the Lambda is invoked, log data is sent to CloudWatch.
  2. CloudWatch collects Lambda log data and sends it to our log-ingestion Lambda.
  3. The log-ingestion Lambda sends that data to New Relic.

Requirements

For requirements and compatibility information, including potential impact on your AWS billing, see Lambda monitoring requirements.

Overview of procedure

This document will explain the following enable steps. Step 1 is optional but highly recommended. Steps 2-4 are required.

  1. Step #1: Install our CLI tool
  2. Step #2: Connect AWS and New Relic
  3. Step #3: Enable instrumentation of your Lambda
  4. Step #4: Stream CloudWatch logs to New Relic

Step 1. Install the newrelic-lambda-cli tool

We provide a CLI tool that's used in steps 2 through 4. This tool is optional but recommended.

If you want to understand what it does before you install it, see the manual procedures that the CLI tool performs in Step 2, Step 3 (option 2), and Step 4. You can also see the CLI documentation on GitHub.

Requirements for using the CLI:

  • Python 3.3 or higher
  • The AWS CLI
  • You must be a New Relic User or Admin with an Infrastructure manager Add-on role.
  • Your AWS account needs permissions for creating IAM resources (Role and Policy) and Lambda functions. These resources are created via CloudFormation stacks, so you'll need permissions to create those. For more on permissions, including setting custom policies, expand this collapser:

    AWS permissions details
    Resource: *
    Actions:
        "cloudformation:CreateChangeSet",
        "cloudformation:CreateStack",
        "cloudformation:DescribeStacks",
        "iam:AttachRolePolicy",
        "iam:CreateRole",
        "iam:GetRole",
        "iam:PassRole",
        "lambda:AddPermission",
        "lambda:CreateFunction",
        "lambda:GetFunction",
        "logs:DeleteSubscriptionFilter",
        "logs:DescribeSubscriptionFilters",
        "logs:PutSubscriptionFilter"
        "s3:GetObject"
    
    Resource: "arn:aws:serverlessrepo:us-east-1:463657938898:applications/NewRelic-log-ingestion"
    Actions:
        "serverlessrepo:CreateCloudFormationTemplate"
        "serverlessrepo:GetCloudFormationTemplate"
    

    Be sure that the AWS account you use to execute the CLI has all of these permissions.

    Note: if your AWS account permissions are restrictive and you're unable to use the CLI, you can optionally use a manually managed custom IAM policy. This policy would require, at minimum, the following permissions:

    Resource: "*"
    Action:      
      "cloudwatch:GetMetricStatistics"
      "cloudwatch:ListMetrics"
      "cloudwatch:GetMetricData"
      "lambda:GetAccountSettings"
      "lambda:ListFunctions"
      "lambda:ListAliases"
      "lambda:ListTags"
      "lambda:ListEventSourceMappings"
    

    These permissions are the minimum required. New Relic recommends granting a managed ReadOnlyAccess policy as described in Connect AWS to New Relic Infrastructure.

To install the CLI tool:

  1. Ensure you have the required permissions for both your New Relic and AWS account.
  2. From the command line, run:
    pip3 install newrelic-lambda-cli
    

Step 2. Connect AWS to New Relic

You must complete this step, and steps 3 and 4, to enable New Relic Lambda monitoring.

To connect AWS and New Relic:

  1. Optional: If you're using multiple AWS profiles or multiple regions, you may want to configure the AWS environment variables:
    AWS environment variable instructions

    Setting the region
    To configure your region, use this environment variable to override the default region:

    export AWS_DEFAULT_REGION=MY_REGION # us-west-2, for example
    

    The CLI tool also allows passing this per-command via --aws-region.

    Setting profiles

    If you have multiple AWS profiles and don't want to use the default, use AWS_DEFAULT_PROFILE environment variable to set another profile name. Ensure the profile is properly configured (including the default region). Example:

    export AWS_DEFAULT_PROFILE=MY_OTHER_PROFILE
    
  2. Run the following command using the CLI tool:

    newrelic-lambda integrations install --nr-account-id YOUR_ACCOUNT_ID \
    --linked-account-name YOUR_LINKED_ACCOUNT_NAME \
    --nr-api-key YOUR_NR_API_KEY
    

    This command :

    • Connects your AWS account to New Relic.
    • Installs a newrelic-log-ingestion Lambda that will send your instrumented data to New Relic.

    More details:

    • This defaults to U.S. region. If your account is in the New Relic EU region, add this argument: --nr-region "eu". If you're instrumenting functions in multiple AWS regions, this command must be run for each region using the --aws-region argument.

    • YOUR_NR_API_KEY refers to your personal API key (not your New Relic REST API key).

    • For more on the API key and other arguments, see New Relic's Lambda monitoring GitHub repo.

Here are the manual procedures performed by the CLI tool:

Manual process: Connect AWS to New Relic

The newrelic-lambda integration command connects the AWS account containing your Lambdas to New Relic. If you've already installed one of New Relic's AWS integrations, your accounts should be linked to New Relic and you can skip this section.

To manually establish this connection, follow the instructions for connecting AWS to New Relic Infrastructure.

Manual process: Configure New Relic's log-ingestion Lambda

The newrelic-lambda integration command sets up a New Relic newrelic-log-ingestion Lambda. This Lambda takes the logs generated by your Lambda functions and pushes those logs to New Relic.

The New Relic Lambda manages Lambdas only for a single region. The CLI, by default, establishes the New Relic Lambda in all regions. If you are doing this manually, you must configure this Lambda for the regions you want.

To manually configure the New Relic Lambda, use the AWS Serverless Application Repository, which is where the newrelic-log-ingestion Lambda is stored. This repo is a collection of serverless applications published by developers, companies, and partners in the serverless community. It allows developers to share their Lambda functions code with customers, who can then find and deploy the corresponding application Lambda function. Each application is packaged with an AWS Serverless Application Model (SAM) template that defines the AWS resources used.

To manually configure the New Relic Lambda with the AWS Serverless Application Repository:

  1. From the AWS console, go to the Lambda section, select Create function, and select Serverless Application Repository.
  2. Search for newrelic and find the newrelic-log-ingestion Lambda. Follow the instructions in the Lambda's documentation to deploy it. A SAM template will build the Lambda.
  3. In the environment variable section in AWS console, set the LICENSE_KEY environment variable to your New Relic license key. Note: If you have multiple accounts or a master-subaccount hierarchy, ensure that the license key used corresponds to the same account connected to AWS.
  4. Optional: If you want to stream all logs to New Relic Logs, set the LOGGING_ENABLED environment variable to true. For more on this, see Stream all logs.

Step 3. Enable Lambda instrumentation

This step enables instrumentation of your Lambda function, which allows detailed monitoring and alerting functionality. Our instrumentation is designed to have minimal impact on your Lambda performance.

You have four options. If you have Node.js or Python, the first two options are recommended.

Option #1 (Node.js and Python): Use Serverless Framework plugin

Requirements

Features

If you meet the requirements (above), you can use our Serverless Framework plugin, which allows you to add the New Relic AWS Lambda Layer to your functions without requiring a code change.

  • Supports Node.js and Python runtimes
  • No code change required to enable New Relic
  • Enables New Relic APM agent functionality using a single layer
  • Configures CloudWatch subscription filters automatically

Install

To install our Serverless Framework plugin:

  1. Choose an install option:
    • NPM:
      npm install --save-dev serverless-newrelic-lambda-layers
      
    • yarn:
      yarn add --dev serverless-newrelic-lambda-layers
      
  2. Add the plugin to your serverless.yml:
    plugins:
      - serverless-newrelic-lambda-layers
      
  3. Get your New Relic account ID and put it in the serverless.yml:
    custom:
      newRelic:
          accountId: YOUR_ACCOUNT_ID
    
  4. Deploy it:
    sls deploy
    

You can skip step 4 (Setting up CloudWatch Logs) as this is automatically completed on deploy by the New Relic Serverless Framework Plugin.

Option #2 (Node.js and Python): Add Lambda Layer with our CLI

Available only for Node.js and Python. For other languages, see Manual instrumentation.

If you don’t have Serverless Framework, you can manually add our New Relic Lambda Layer:

  1. Install the CLI:
    pip3 install newrelic-lambda-cli
  2. List available functions:
    newrelic-lambda functions list
    Pass the option -f not-installed to see which functions have not yet been instrumented.
  3. Add the layer to your function:
    newrelic-lambda layers install --function FUNCTION_NAME --nr-account-id NEW_RELIC_ACCOUNT_ID

Next, you will configure CloudWatch to send logs to New Relic.

Option #3 (Node.js and Python): Manually add our Lambda Layer

Available only for Node.js and Python. For other languages, see Manual instrumentation.

If you don’t have Serverless Framework, you can manually add our New Relic Lambda Layer:

  1. Find the New Relic layer that matches your runtime and region.
  2. Copy the ARN of the most recent version and add it in the AWS Lambda console for your function.
  3. Update your functions handler to point to the newly attached layer in the console for your function:
    • Python: newrelic_lambda_wrapper.handler
    • Node: newrelic-lambda-wrapper.handler
  4. Add these environment variables to your Lambda console:
    • NEW_RELIC_ACCOUNT_ID: Your New Relic account ID
    • NEW_RELIC_LAMBDA_HANDLER: Path to your initial handler.

If you have Node 8 and get a Lambda can't find file error message, expand this collapser:

Node 8 "can't find file" errror troubleshooting

If you have Node 8 and receive a Lambda can't find the file newrelic-lambda-wrapper.js messsage, it's likely that the Node runtime isn't resolving NPM_PATH for the newrelic-lambda module in /opt/nodejs/node_modules. These steps should fix this problem:

  • Create a newrelic-wrapper-helper.js script in your project's root.
  • The script's contents should be module.exports = require('newrelic-lambda-wrapper');. (That is all that needs to be in that script.)
  • Update the handler for your layer declaration to newrelic-lambda-wrapper.handler.

Next, you will configure CloudWatch to send logs to New Relic.

Option #4 (Go, Java, .NET Core, Node.js, Python): Manually instrument Lambda code

Available for these languages: Go, Java, .NET Core, Node.js, Python.

If none of the previous options work for you, you can manually instrument your Lambda code. Choose your language:

Go

To instrument your Go-language Lambda:

  1. Download the New Relic Go agent package and place it in the same directory as your function. To install the agent, call go get -u github.com/newrelic/go-agent.

  2. In your Lambda code, import the New Relic components, create an application, and update how you start your Lambda. See the New Relic github for an example of an instrumented Lambda.
  3. Optional: 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!")
    }
    
  4. Build and zip your Lambda function and upload it to AWS.

    Zip and upload recommendations

    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:
      $ GOOS=linux go build -o main
      
    • Zip the binary into a deployment package using:

      $ zip deployment.zip main
      
    • Upload 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).

  5. These 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 New Relic account ID.
    • NEW_RELIC_TRUSTED_ACCOUNT_KEY. Also your New Relic account ID. If your New Relic account is a sub-account, this needs to be the account ID for the root/parent account.
  6. Optional: To configure logging, see Go agent logging.
  7. 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 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.

Java

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.
  • New Relic AWS Lambda OpenTracing Tracer: A New Relic OpenTracing Tracer implementation designed to monitor AWS Lambda. It generates span events, error events, transaction events, error traces, and provides distributed tracing support.

To instrument your Java Lambda:

  1. In your project’s build.gradle file, include the New Relic OpenTracing AWS Lambda Tracer and the AWS Lambda OpenTracing SDK dependencies:

    dependencies {
           compile("com.newrelic.opentracing:java-aws-lambda:VERSION")
           compile("com.newrelic.opentracing:newrelic-java-lambda:VERSION")
    }
    
  2. Implement the TracingRequestHandler interface as shown in the Java Lambda example, defining the Lambda function input and output types that your function requires and overriding the doHandleRequest method.

    If you are refactoring a pre-existing Lambda handler to take advantage of this SDK's TracingRequestHandler, ensure it overrides doHandleRequest, rather than handleRequest.

  3. Register a LambdaTracer.INSTANCE as the OpenTracing Global tracer, as shown in the Java Lambda example.

    For the LambdaTracer to be fully functional, it must be used in conjunction with the TracingRequestHandler interface provided by the AWS Lambda OpenTracing Java SDK. If a different request handler is used, the LambdaTracer won't be able to generate error events or traced errors.

  4. Create a ZIP deployment package and upload it to AWS Lambda.
  5. In the AWS Lambda console, set the handler. For the example Java Lambda, the handler would be com.handler.example.MyLambdaHandler::handleRequest. Because handleRequest is assumed, you could also use com.handler.example.MyLambdaHandler.

  6. 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 New Relic account ID.
    • NEW_RELIC_PRIMARY_APPLICATION_ID. New Relic application ID.
    • NEW_RELIC_TRUSTED_ACCOUNT_KEY. Also your New Relic account ID. If your New Relic account is a sub-account, this must be the account ID for the root/parent account.
  7. Optional: In the Lambda console, enable debug logging by adding this environment variable: NEW_RELIC_DEBUG is true.
  8. 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 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.

Here's an example of a New Relic-instrumented Java Lambda:

package com.handler.example;

import com.amazonaws.services.lambda.runtime.Context;
import io.opentracing.util.GlobalTracer;
import com.newrelic.opentracing.aws.TracingRequestHandler;
import com.newrelic.opentracing.LambdaTracer;

import java.util.Map;

/**
 * Tracing request handler that creates a span on every invocation of a Lambda.
 *
 * @param Map<String, Object> The Lambda Function input
 * @param String The Lambda Function output
 */
public class MyLambdaHandler implements TracingRequestHandler<Map<String, Object>, String> {
    static {
        // Register the New Relic OpenTracing LambdaTracer as the Global Tracer
        GlobalTracer.registerIfAbsent(LambdaTracer.INSTANCE);
    }

    /**
     * Method that handles the Lambda function request.
     *
     * @param input The Lambda Function input
     * @param context The Lambda execution environment context object
     * @return String The Lambda Function output
     */
    @Override
    public String doHandleRequest(Map<String, Object> input, Context context) {
        // TODO Your function logic here
        return "Lambda Function output";
    }
}
.NET Core

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:

  1. In your Lambda Functions project, install the NewRelic.OpenTracing.AmazonLambda.Tracer NuGet package.

  2. Instrument your function, as shown in this example:
    public class Function
    {
    
      static Function()
      {
        // Register The NewRelic Lambda Tracer Instance
        GlobalTracer.Register(NewRelic.OpenTracing.AmazonLambda.LambdaTracer.Instance);
      }
    
      public object FunctionWrapper(ILambdaContext context)
      {
        // Instantiate NewRelic TracingWrapper and pass your FunctionHandler as 
        // an argument
        return 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)
      { ... }
    
    }
    

    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. For an example of how this is done, see below:

    Async handler function
    public override Task<int> FunctionHandlerAsync(ILambdaContext lambdaContext)
    {
      // This call will block by calling task.Result 
      Task<int> task = new TracingRequestHandler().LambdaWrapper(
                                       ActualFunctionHandlerAsync, lambdaContext);
      return task;
    }
    
    public Task<APIGatewayProxyResponse> ActualFunctionHandlerAsync(ILambdaContext 
                                                                    lambdaContext)
    { // Function can make other async operations here
      ... 
    }
  3. Optional for SQS and SNS: Starting in version 1.0 of the New Relic .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.

    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.

    1. Set the NEW_RELIC_USE_DT_WRAPPER environment variable to true.

    2. To instrument SQS and SNS calls you will need to use the provided wrappers.

      Using the SQS Wrapper

      The SQS wrapper supports wrapping the following methods:

      • Amazon.SQS.AmazonSQSClient.SendMessageAsync(...)

      • Amazon.SQS.AmazonSQSClient.SendMessageBatchAsync(...)

      Examples

      // SQS Client
      AmazonSQSClient client = new AmazonSQSClient("AWS_SECRET_ACCESS_KEY", AWS_REGION);
      
      
      // SendMessageRequest
      SendMessageRequest sendRequest = new SendMessageRequest("QUEUE_URI_STRING", "An SQS Message");
      Task<SendMessageResponse> responseOne = SQSWrapper.WrapRequest(client.SendMessageAsync, sendRequest);
      
      
      // String-based
      Task<SendMessageResponse> responseTwo = SQSWrapper.WrapRequest(client.SendMessageAsync, "QUEUE_URI_STRING", "Another SQS Message");
      
      
      // SendMessageBatchRequest
      List<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 List
      List<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);
                          
      Using the SNS Wrapper

      The SNS wrapper supports wrapping the following methods:

      • Amazon.SimpleNotificationService.AmazonSimpleNotificationServiceClient.PublishAsync(...)

      Examples

      // SNS Client
      AmazonSimpleNotificationServiceClient client = new Amazon.SimpleNotificationService.AmazonSimpleNotificationServiceClient("AWS_SECRET_ACCESS_KEY", AWS_REGION);
      
      
      // PublishRequest - Phone Number
      PublishRequest phonePublishRequest = new PublishRequest();
      phonePublishRequest.PhoneNumber = +1XXX5555100;
      phonePublishRequest.Message = "An SNS Message for phones";
      Task<PublishResponse> phoneResponse = SNSWrapper.WrapRequest(client.PublishAsync, phonePublishRequest);
      
      
      // PublishRequest - ARN
      PublishRequest publishRequest = new PublishRequest("TOPIC_ARN", "An SNS Message");
      Task<PublishResponse> publishResponse = SNSWrapper.WrapRequest(client.PublishAsync, publishRequest);
      
      
      // String-based without subject
      Task<PublishResponse> ResponseOne = SNSWrapper.WrapRequest(client.PublishAsync, "TOPIC_ARN", "Another SNS Message");
      
      
      // String-based with subject
      Task<PublishResponse> ResponseTwo = SNSWrapper.WrapRequest(client.PublishAsync, "TOPIC_ARN", "Yet Another SNS Message", "A Subject");
                          
  4. These 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 New Relic account ID the Lambda is reporting to.
    • NEW_RELIC_TRUSTED_ACCOUNT_KEY: Also the New Relic account ID. If your New Relic account is a sub-account, this needs to be the account ID for the root/parent account.
  5. Ensure that the wrapper function (FunctionWrapper in above example) is set up as the function handler.
  6. 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 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.

Node.js

To instrument your Node.js Lambda:

  1. Download the New Relic 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. To do this using Node Package Manager:

    npm install newrelic --save
    
  2. Install New Relic's AWS SDK module alongside the New Relic agent by running

    npm install @newrelic/aws-sdk --save
    
  3. In your Lambda code, require the agent module and the AWS SDK at the top of the file, and wrap the handler function. For example:

    const newrelic = require('newrelic');
    require('@newrelic/aws-sdk');
    
    <Other module loads go under the two require statements above>
    
    module.exports.handler = newrelic.setLambdaHandler((event, context, callback) => {
      // This is your handler function code
      console.log('Lambda executed');
      callback();
    });
    
  4. 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();
    });
    
  5. Zip your Lambda function and the New Relic 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 file lambda_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.

  6. Upload the zipped file to your AWS Lambda account.
  7. In the AWS console, set these environment variables:

    • NEW_RELIC_NO_CONFIG_FILE. Set to true if not using a configuration file.
    • NEW_RELIC_APP_NAME: Your application name .
    • NEW_RELIC_ACCOUNT_ID. Your New Relic account ID.
    • NEW_RELIC_TRUSTED_ACCOUNT_KEY. Also your New Relic account ID. If your New Relic account is a sub-account, this needs to be the account ID for the root/parent account.
  8. Optional: To run the agent in serverless mode outside of AWS in a local environment, set environment variable NEW_RELIC_SERVERLESS_MODE_ENABLED to true. (When executing in an AWS Lambda environment, the agent will automatically run in serverless mode. Do not use this variable if you are running in AWS.)
  9. Optional: To enable logging in serverless mode, set these environment variables:
    • Set NEW_RELIC_LOG_ENABLED to true.
    • Set NEW_RELIC_LOG to stdout for output to CloudWatch, or set to any writeable file location.
    • The log level is set to info by default. See other log levels.
  10. 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 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.

Python

To instrument your Python Lambda:

  1. Download the New Relic Python agent package and place it in the same directory as your function. To do this using pip:

    pip install -t . newrelic
    

    If you use Homebrew, you may receive this error:

    DistutilsOptionError: must supply either home or prefix/exec-prefix -- not both

    For more information, see the Homebrew GitHub post.

  2. In your Lambda code, import the 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.agent
    newrelic.agent.initialize()
    
    @newrelic.agent.lambda_handler()
    def handler(event, context):
    ...
    
  3. 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'})
    …
    
  4. Zip your lambda_function.py and newrelic/ folder together. Requirements and recommendations:

    • 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 file lambda_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.

  5. Upload the zipped file to your AWS Lambda account.
  6. In the AWS console, set this environment variable:

    • NEW_RELIC_SERVERLESS_MODE_ENABLED. Set to true
  7. These 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 New Relic account ID.
    • NEW_RELIC_TRUSTED_ACCOUNT_KEY. Also your New Relic account ID. If your New Relic account is a sub-account, this needs to be the account ID for the root/parent account.
  8. Optional: To configure logging, use the NEW_RELIC_LOG and NEW_RELIC_LOG_LEVEL environment variables in the AWS Console.
  9. 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.

Step 4. Configure CloudWatch logs to stream to New Relic Lambda

Next, you'll run a command that links your Lambda function's CloudWatch Logs stream to the newrelic-log-ingestion Lambda that was configured in Step 2.

For Node.js and Python: This step is not necessary if you used the Serverless Framework plugin option in Step 3.

Run this command for every Lamba function you want to monitor:

newrelic-lambda subscriptions install --function FUNCTION_NAME_#1

Notes on this command:

  • You should only need one newrelic-log-ingestion Lambda per AWS account and region. You can subscribe as many functions to it as you like.
  • To see more detail about the arguments, including a region-specifying argument, see our GitHub documentation.
  • You may receive a CloudWatch validation error. This should not affect data reporting. If you see data reporting in New Relic, disregard that error message.

If you have New Relic Logs and want to send all your log data to us (not just Lambda logs), see Stream all logs.

Here are the manual procedures performed by the CLI tool:

Manual process: Stream CloudWatch logs to New Relic Lambda

In Step 2, you set up a newrelic-log-ingestion Lambda function. After you've instrumented your Lambda function (Step 3), the newrelic-lambda subscriptions command links that function's CloudWatch Logs stream to the newrelic-log-ingestion Lambda. To do this manually:

  1. Open CloudWatch and select Logs in the left-hand menu, and then select the log group for the function you are monitoring.
  2. Select Actions and choose Stream to AWS Lambda.
  3. Under Lambda function, select the newrelic-log-ingestion function.
  4. Set the Log format to JSON.
  5. Set the Subscription filter pattern NR_LAMBDA_MONITORING. Optional: If you use New Relic Logs, you can stream all your logs to New Relic.

See notes and caveats about this procedure.

Check your account for data

If all enable procedure steps have been completed correctly, you should see data reporting in the Lambda monitoring UI.

Having problems or not seeing data? See Lambda enable troubleshooting.

Optional: Stream all logs to New Relic Logs

If you have New Relic Logs and want to report all your logs to New Relic, follow these instructions:

  1. Go to the New Relic newrelic-log-ingestion Lambda and set the LOGGING_ENABLED environment variable to true.
  2. It is not possible to edit existing filter patterns, so they must be removed and re-added:
    1. Remove the NR_LAMBDA_MONITORING Subscription filter pattern. Go to the Log group for each monitored Lambda, and remove the newrelic-log-ingestion subscription.
    2. Add the subscription filter back, leaving the Subscription filter pattern field blank.

For more help

Recommendations for learning more: