Skip to content

Latest commit

 

History

History
456 lines (352 loc) · 24.3 KB

enable-serverless-monitoring-aws-lambda-legacy.mdx

File metadata and controls

456 lines (352 loc) · 24.3 KB
title metaDescription redirects
Legacy manual instrumentation for Lambda monitoring
Legacy instructions for manually enabling New Relic monitoring for Amazon AWS Lambda.
/docs/install-enable-new-relics-monitoring-aws-lambda
/docs/net-core-new-relic-monitoring-aws-lambda
/node/38236
/docs/serverless-function-monitoring/aws-lambda-monitoring/get-started/enable-new-relic-monitoring-aws-lambda
/docs/serverless-function-monitoring/aws-lambda-monitoring/get-started/enable-serverless-monitoring-aws-lambda
/docs/serverless-function-monitoring/aws-lambda-monitoring/enable-lambda-monitoring/enable-serverless-monitoring-aws-lambda
/docs/understand-dependencies/distributed-tracing/enable-configure/aws-lambda

On this page, you will learn how to manually instrument your lambda function. It's organized by runtime language.

To instrument your Go-language Lambda:
1. Download our Go agent package and place it in the same directory as your function.
2. Install the agent: `go get -u github.com/newrelic/go-agent/v3/newrelic`.
3. Install the nrlambda integration `go get -u github.com/newrelic/go-agent/v3/integrations/nrlambda`.
4. In your Lambda code, import our components, create an application, and update how you start your Lambda. See our [GitHub repo for an example of an instrumented Lambda](https://github.com/newrelic/go-agent/blob/master/_integrations/nrlambda/example/main.go).
5. Optional: Add [custom events](/docs/using-new-relic/welcome-new-relic/getting-started/glossary#custom-event) that will be associated with your Lambda invocation by using the [`RecordCustomEvent` API](/docs/agents/go-agent/features/create-custom-events-insights-go). For example:

    ```go
    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!")
    }
    ```
6. Build and zip your Lambda function and upload it to AWS.


  <CollapserGroup>
    <Collapser
      id="zip-upload"
      title="Zip and upload recommendations"
    >
      Here are suggestions for zipping and uploading the Lambda:

      1. Build the binary for execution on Linux. This produces a binary file called `main`. You can use:

        ```
        $ GOOS=linux go build -o main
        ```
      2. Zip the binary into a deployment package using:

        ```
        $ zip deployment.zip main
        ```
      3. 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).
    </Collapser>
  </CollapserGroup>

  6. 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](/docs/apm/distributed-tracing/getting-started/introduction-distributed-tracing), set these [environment variables](https://docs.aws.amazon.com/amplify/latest/userguide/environment-variables.html) in the AWS console:
     * `NEW_RELIC_ACCOUNT_ID`. Your [account ID](/docs/accounts/install-new-relic/account-setup/account-id).
     * `NEW_RELIC_TRUSTED_ACCOUNT_KEY.` This is also your [account ID](/docs/accounts/install-new-relic/account-setup/account-id). If your account is a child account, this is the account ID for the root/parent account.
  7. Optional: To configure logging, see [Go agent logging](/docs/agents/go-agent/configuration/go-agent-logging).
  8. 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](/docs/serverless-function-monitoring/aws-lambda-monitoring/enable-lambda-monitoring/instrument-your-own/#manual-stream-logs).

<Collapser id="java" title="Java"

Monitoring for AWS Lambda in Java doesn't use our [APM Java agent](/docs/agents/java-agent). Instead, it uses these two OpenTracing dependencies:

* AWS Lambda OpenTracing Java SDK: [OpenTracing](https://github.com/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.

<Callout variant="tip">
  **Supported OpenTracing Versions**

  * **OpenTracing 0.31.0**:
    * Lambda Tracer: [com.newrelic.opentracing:newrelic-java-lambda:1.1.1](https://search.maven.org/artifact/com.newrelic.opentracing/newrelic-java-lambda/1.1.1/jar)
    * Lambda SDK: [com.newrelic.opentracing:java-aws-lambda:1.0.0](https://search.maven.org/artifact/com.newrelic.opentracing/java-aws-lambda/1.0.0/jar)
  * **OpenTracing 0.32.0, 0.33.0**:
    * Lambda Tracer: [com.newrelic.opentracing:newrelic-java-lambda:2.1.1](https://search.maven.org/artifact/com.newrelic.opentracing/newrelic-java-lambda)
    * Lambda SDK: [com.newrelic.opentracing:java-aws-lambda:2.1.0](https://search.maven.org/artifact/com.newrelic.opentracing/java-aws-lambda)
</Callout>

To instrument your Java Lambda:

1. 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.1.1")
      compile("io.opentracing:opentracing-util:0.33.0")
  }
  ```
2. Implement the AWS Lambda `RequestHandler` interface as shown in the [Java Lambda example](https://github.com/newrelic/newrelic-lambda-tracer-java#usage) and override the `doHandleRequest` method.
3. In the `doHandleRequest` method, call the `LambdaTracing.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.
4. Register a `LambdaTracer.INSTANCE` as the OpenTracing Global tracer, as shown in the [Java Lambda example](https://github.com/newrelic/newrelic-lambda-tracer-java#usage).
5. [Create a ZIP deployment package](https://docs.aws.amazon.com/lambda/latest/dg/java-package.html) and upload it to AWS Lambda. Or deploy it via other means.
6. In the AWS Lambda console, set the handler. For the [example Java Lambda](https://github.com/newrelic/newrelic-lambda-tracer-java#usage), the handler would be `com.handler.example.MyLambdaHandler::handleRequest`. Because `handleRequest` is assumed, you could also use `com.handler.example.MyLambdaHandler`.
7. The following [AWS console environment variables](https://docs.aws.amazon.com/amplify/latest/userguide/environment-variables.html) are required if you want your Lambda function to be included in [distributed tracing](/docs/apm/distributed-tracing/getting-started/introduction-distributed-tracing). This is recommended.
    * `NEW_RELIC_ACCOUNT_ID`. Your [account ID](/docs/accounts/install-new-relic/account-setup/account-id).
    * `NEW_RELIC_PRIMARY_APPLICATION_ID`. This is also your [account ID](/docs/accounts/install-new-relic/account-setup/account-id).
    * `NEW_RELIC_TRUSTED_ACCOUNT_KEY`. This is also your [account ID](/docs/accounts/install-new-relic/account-setup/account-id). If your account is a child account, this must be the account ID for the root/parent account.
8. Optional: In the Lambda console, enable debug logging by adding this environment variable: `NEW_RELIC_DEBUG` is `true`.
9. 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](/docs/serverless-function-monitoring/aws-lambda-monitoring/enable-lambda-monitoring/instrument-your-own/#manual-stream-logs).

Please see the [AWS Lambda distributed tracing example](https://github.com/newrelic/newrelic-lambda-tracer-java/tree/main/examples/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

<Collapser id="net-core" title=".NET Core"

Our monitoring of .NET Core-based AWS Lambda functions doesn't use our standard [.NET Core APM agent](/docs/agents/net-agent/installation/compatibility-requirements-net-core-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.

    Note: `NewRelic.OpenTracing.AmazonLambda.Tracer` depends on version 1.2.0+ of `Amazon.Lambda.APIGatewayEvent` NuGet package. If the environment already uses a lower version of `Amazon.Lambda.APIGatewayEvent`, the New Relic package may produce errors such as `System.MissingMethodException` .
2. Import the NuGet package and OpenTracing utils:

    ```
    using OpenTracing.Util;
    using NewRelic.OpenTracing.AmazonLambda;
    ```

3. 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)
{ ... }

}
    <Callout variant="tip">
      The arguments passed to `FunctionWrapper` must match the signature of `FunctionHandler`.
    </Callout>

    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 FunctionHandlerAsync(ILambdaContext lambdaContext) { return await new TracingRequestHandler().LambdaWrapper( ActualFunctionHandlerAsync, lambdaContext); }

public async Task ActualFunctionHandlerAsync(ILambdaContext lambdaContext) { // Function can make other async operations here ... }

</Collapser>

<Collapser
id="net-handler-inherit-apigatewayproxyfunction"
title="Inheriting from APIGatewayProxyFunction"
>

public class LambdaFunction : APIGatewayProxyFunction { static LambdaFunction() { // Register The NewRelic Lambda Tracer Instance OpenTracing.Util.GlobalTracer.Register(NewRelic.OpenTracing.AmazonLambda.LambdaTracer.Instance); }

public override Task FunctionHandlerAsync(APIGatewayProxyRequest request, ILambdaContext lambdaContext) { Task task = new TracingRequestHandler().LambdaWrapper(ActualFunctionHandlerAsync, request, lambdaContext); return task; }

public Task ActualFunctionHandlerAsync(APIGatewayProxyRequest request, ILambdaContext lambdaContext) { return base.FunctionHandlerAsync(request, lambdaContext); } }

</Collapser>
</CollapserGroup>
    4. Optional for SQS and SNS: Starting in version 1.0 of our .NET Lambda Tracer, [distributed tracing](/docs/apm/distributed-tracing/getting-started/introduction-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.

        <Callout variant="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.
        </Callout>

        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.

<CollapserGroup>
<Collapser
id="net-dt-sqs"
title="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 responseOne = SQSWrapper.WrapRequest(client.SendMessageAsync, sendRequest);

// String-based Task responseTwo = SQSWrapper.WrapRequest(client.SendMessageAsync, "QUEUE_URI_STRING", "Another SQS Message");

// SendMessageBatchRequest List batchEntries = new List(); 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 response = SQSWrapper.WrapRequest(client.SendMessageBatchAsync, sendBatchRequest);

// SendMessageBatchRequestEntry List List moreBatchEntries = new List(); 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 response = SQSWrapper.WrapRequest(client.SendMessageBatchAsync, moreBatchEntries);

</Collapser>

<Collapser
id="net-dt-sns"
title="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 phoneResponse = SNSWrapper.WrapRequest(client.PublishAsync, phonePublishRequest);

// PublishRequest - ARN PublishRequest publishRequest = new PublishRequest("TOPIC_ARN", "An SNS Message"); Task publishResponse = SNSWrapper.WrapRequest(client.PublishAsync, publishRequest);

// String-based without subject Task ResponseOne = SNSWrapper.WrapRequest(client.PublishAsync, "TOPIC_ARN", "Another SNS Message");

// String-based with subject Task ResponseTwo = SNSWrapper.WrapRequest(client.PublishAsync, "TOPIC_ARN", "Yet Another SNS Message", "A Subject");

</Collapser>
</CollapserGroup>
    5. 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](/docs/apm/distributed-tracing/getting-started/introduction-distributed-tracing), set these environment variables in the [AWS Lambda console](https://docs.aws.amazon.com/lambda/latest/dg/env_variables.html):
        * `NEW_RELIC_ACCOUNT_ID`: The [account ID](/docs/accounts/install-new-relic/account-setup/account-id) the Lambda is reporting to.
        * `NEW_RELIC_TRUSTED_ACCOUNT_KEY`: This is also the [account ID](/docs/accounts/install-new-relic/account-setup/account-id). If your account is a child account, this needs to be the account ID for the root/parent account.
    6. Ensure that the wrapper function (`FunctionWrapper` in above example) is set up as the function handler.
    7. 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](/docs/serverless-function-monitoring/aws-lambda-monitoring/enable-lambda-monitoring/instrument-your-own/#manual-stream-logs).
  </Collapser>

<Collapser
id="node"
title="Node.js"
>
To instrument your Node.js Lambda:

1. 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:

npm install newrelic --save

2. Install our AWS SDK module alongside the Node.js agent:

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](/docs/using-new-relic/welcome-new-relic/getting-started/glossary#custom-event) to your Lambda using the [`recordCustomEvent` API](/docs/agents/nodejs-agent/api-guides/nodejs-agent-api#record_custom_event). 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 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 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](https://docs.aws.amazon.com/lambda/latest/dg/env_variables.html):

    * `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 [account ID](/docs/accounts/install-new-relic/account-setup/account-id).
    * `NEW_RELIC_TRUSTED_ACCOUNT_KEY`. This is also your [account ID](/docs/accounts/install-new-relic/account-setup/account-id). If your account is a child 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 the environment variable `NEW_RELIC_SERVERLESS_MODE_ENABLED` to `true`. (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**.)
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](/docs/agents/nodejs-agent/installation-configuration/nodejs-agent-configuration#logging_config).
10. 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](/docs/serverless-function-monitoring/aws-lambda-monitoring/enable-lambda-monitoring/instrument-your-own/#manual-stream-logs).
</Collapser>

<Collapser
id="python"
title="Python"
>
To instrument your Python Lambda:

1. Download our Python agent package and place it in the same directory as your function. To do this, use pip:

pip install -t . newrelic


<Callout variant="important">
  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](https://github.com/Homebrew/brew/blob/master/docs/Homebrew-and-Python.md#note-on-pip-install---user).
</Callout>
2. 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.agent newrelic.agent.initialize() @newrelic.agent.lambda_handler() def handler(event, context): ...

3. Optional: You can also add [custom events](/docs/using-new-relic/welcome-new-relic/getting-started/glossary#custom-event) to your Lambda using the [`record_custom_event` API](/docs/agents/python-agent/python-agent-api/record_custom_event). 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 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 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](https://docs.aws.amazon.com/lambda/latest/dg/env_variables.html):

      * `NEW_RELIC_SERVERLESS_MODE_ENABLED`. Set to `true`
  7. 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](/docs/apm/distributed-tracing/getting-started/introduction-distributed-tracing), set these [environment variables](https://docs.aws.amazon.com/amplify/latest/userguide/environment-variables.html) in the AWS console:
      * `NEW_RELIC_DISTRIBUTED_TRACING_ENABLED`. Set to true.
      * `NEW_RELIC_ACCOUNT_ID`. Your [account ID](/docs/accounts/install-new-relic/account-setup/account-id).
      * `NEW_RELIC_TRUSTED_ACCOUNT_KEY.` This is also your [account ID](/docs/accounts/install-new-relic/account-setup/account-id). If your account is a child 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](/docs/agents/python-agent/configuration/python-agent-configuration#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](/docs/serverless-function-monitoring/aws-lambda-monitoring/enable-lambda-monitoring/instrument-your-own/#manual-stream-logs).
</Collapser>
</CollapserGroup>