Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
152 changes: 152 additions & 0 deletions docs/monitoring-aws-lambda.asciidoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
[[aws-lambda-extension]]
= AWS Lambda Extension (Experimental)

experimental::[]

Elastic's APM Agents instrument AWS Lambda functions and dispatch APM data via an AWS Lambda Extension.

[discrete]
[[aws-lambda-arch]]
== Extension Architecture

Normally, during the execution of a Lambda function, there's only a single language process running in the AWS Lambda execution environment. However, with an AWS Lambda Extension, Lambda users can run a _second_ process alongside their main service/application process.

image:images/data-flow.png[image showing data flow from lambda function, to extension, to APM Server]

By using a custom-built AWS Lambda Extension, Elastic APM Agents can send data to a locally running Lambda Extension process, and that process will forward data on to APM Server. The Lambda Extension ensures that any latency between the Lambda function and the AWS Server instance will not cause latency in the Lambda function/Service itself.

[discrete]
[[aws-lambda-instrumenting]]
== Instrumenting a Lambda Function

The rest of this guide contains instructions for instrumenting a Lambda function. There are two high level steps to instrumenting an AWS Lambda function.

1. <<aws-lambda-configure-layer>>
2. <<aws-lambda-handler>>

[discrete]
[[aws-lambda-configure-layer]]
=== Configuring the APM Lambda Extension Layer

First, you'll need to https://github.com/elastic/apm-aws-lambda/releases[pick the right ARN from the extension release table] for your AWS Lambda function. The ARN has the pattern `arn:aws:lambda:<AWS_REGION_KEY>:267093732750:layer:elastic-apm-extension-<APM_EXTENSION_VERSION>-<ARCHITECTURE_KEY>:<LAYER_VERSION>` and depends on:

* The AWS region your Lambda function runs in. The APM Lambda Extension layer needs to be in the same region as your Lambda function.
* The architecture (_x86_64_ or _arm64_) used for your Lambda function.
* The version of the APM Lambda Extension you would like to use.

You'll then need to configure your function to use that layer. To add a layer

1. Navigate to your function in the AWS Console
2. Scroll to the Layers section and click the _Add a layer_ button image:images/config-layer.png[image of layer configuration section in AWS Console]
3. Choose the _Specify an ARN_ radio button
4. Enter the Version ARN of the APM Lambda Extension layer in the _Specify an ARN_ text input
5. Click the _Add_ button

[discrete]
[[aws-lambda-env-vars]]
==== Configure Environment Variables

Finally, once the layer's in place you'll need to configure a few environment variables. To configure variables

1. Navigate to your function in the AWS Console
2. Click on the _Configuration_ tab
3. Click on _Environment variables_
4. Add the necessary variables.

The following environment variables are relevant for instrumenting a Lambda function:

* (required) `ELASTIC_APM_LAMBDA_APM_SERVER`: +
This required config option controls where the Lambda extension will ship data. This should be the URL of the final APM Server destination for your telemetry.

* (required) `ELASTIC_APM_SECRET_TOKEN` or `ELASTIC_APM_API_KEY`: +
One of these needs to be set as the authentication method that the extension uses when sending data to the URL configured via `ELASTIC_APM_LAMBDA_APM_SERVER`.

* (optional) `ELASTIC_APM_SERVICE_NAME`: +
The configured name of your application or service. The APM Agent will use this value when reporting data to APM Server. If unset, the APM Agent will automatically set the value based on the Lambda function name. Use this config option if you want to group multiple Lambda functions under a single service entity in APM.

* (optional) `ELASTIC_APM_DATA_RECEIVER_TIMEOUT_SECONDS`: +
The timeout value, in seconds, for the Lambda Extension's server receiving data from the agent. The _default_ is `15`.

* (optional) `ELASTIC_APM_SEND_STRATEGY`: +
Whether to synchronously flush APM agent data from the extension to the APM server at the end of the function invocation.
The two accepted values are `background` and `syncflush`. The _default_ is `syncflush`.
** The `background` strategy indicates that the extension will not flush when it receives a signal that the function invocation
has completed. It will instead send any remaining buffered data on the next function invocation. The result is that, if the
function is not subsequently invoked for that Lambda environment, the buffered data will be lost. However, for lambda functions
that have a steadily frequent load pattern the extension could delay sending the data to the APM server to the next lambda
request and do the sending in parallel to the processing of that next request. This potentially would improve both the lambda
function response time and its throughput.
** The other value, `syncflush` will synchronously flush all remaining buffered APM agent data to the APM server when the
extension receives a signal that the function invocation has completed. This strategy blocks the lambda function from receiving
the next request until the extension has flushed all the data. This has a negative effect on the throughput of the function,
though it ensures that all APM data is sent to the APM server.

An example configuration of the APM Lambda Extension might look like the following

[source,bash]
----
ELASTIC_APM_LAMBDA_APM_SERVER=https://your-apm-server-url:443 # (required) this is your APM Server URL
ELASTIC_APM_SECRET_TOKEN=shhhhhhitsasecret # (required) this is your APM Server's secret token
ELASTIC_APM_SERVICE_NAME=yourApmServiceName # (optional) use this to group multiple lambda functions
ELASTIC_APM_DATA_RECEIVER_TIMEOUT_SECONDS=20 # (optional) wait 20s to receive data from the APM agent
ELASTIC_APM_SEND_STRATEGY=background # (optional) this is the default strategy
----

For a _minimal configuration_ you need to specify the `ELASTIC_APM_LAMBDA_APM_SERVER` and the `ELASTIC_APM_SECRET_TOKEN` config options.

[discrete]
[[aws-lambda-handler]]
=== Configuring the Agent and Lambda Function handler

After the extension has been installed, install the relevant language agent and wrap the Lambda function handler.


[discrete]
[[aws-lambda-nodejs]]
==== Node.js

To install the Node.js agent in Lambda you'll use a second layer. You'll need to https://github.com/elastic/apm-agent-nodejs/releases[pick the right ARN from the agent release table]. The ARN has the pattern `arn:aws:lambda:<AWS_REGION_KEY>:267093732750:layer:elastic-apm-node-ver-<APM_EXTENSION_VERSION>:<LAYER_VERSION>` and depends on:

* The AWS region your Lambda function runs in. The APM Lambda Extension layer needs to be in the same region as your Lambda function.
* The version of the APM Lambda Extension you would like to use.

You'll then need to configure your function to use that layer. To add a layer

1. Navigate to your function in the AWS Console
2. Scroll to the Layers section and click the _Add a layer_ button image:images/config-layer.png[image of layer configuration section in AWS Console]
3. Choose the _Specify an ARN_ radio button
4. Enter the Version ARN of the APM Lambda Extension layer in the _Specify an ARN_ text input
5. Click the _Add_ button

Finally, to have the Node.js agent automatically wrap your Lambda function handler, add the following environment variable.

[source]
---
NODE_OPTIONS=-r elastic-apm-node/start
---

See the {apm-node-ref}/lambda.html[Node.js agent setup guide] for detailed instructions on setting up the Node.js agent for AWS Lambda.

[discrete]
[[aws-lambda-python]]
==== Python

In Python, you wrap a Lambda function handler using the following syntax.

[source,python]
----
from elasticapm import capture_serverless
@capture_serverless()
def handler(event, context):
return {"statusCode": r.status_code, "body": "Success!"}
----

See the {apm-py-ref}/lambda-support.html[Python agent setup guide] for detailed instructions on setting up the Python agent for AWS Lambda.

[discrete]
[[aws-lambda-java]]
==== Java

Like the extension, the Elastic APM Java agent is installed as a Lambda layer.

See the {apm-java-ref}/aws-lambda.html[Java agent setup guide] for detailed instructions on setting up the Java agent for AWS Lambda.