diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index 568ed6d24..934573973 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -36,6 +36,7 @@ endif::[] [float] ===== Features +* Add lambda layer for instrumenting AWS Lambda functions {pull}1826[#1826] * Implement instrumentation of Azure Functions {pull}1766[#1766] * Add support for Django to wrapper script {pull}1780[#1780] * Add `transport_json_serializer` configuration option {pull}1777[#1777] diff --git a/docs/lambda/configure-lambda.asciidoc b/docs/lambda/configure-lambda.asciidoc index 076cf288d..09377dcee 100644 --- a/docs/lambda/configure-lambda.asciidoc +++ b/docs/lambda/configure-lambda.asciidoc @@ -1,4 +1,4 @@ -// tag::console-extension-only[] +// tag::console-with-agent[] To configure APM through the AWS Management Console: @@ -9,30 +9,31 @@ To configure APM through the AWS Management Console: [source,bash] ---- -ELASTIC_APM_LAMBDA_APM_SERVER = # this is your APM Server URL -ELASTIC_APM_SECRET_TOKEN = # this is your APM secret token -ELASTIC_APM_SEND_STRATEGY = background <1> +AWS_LAMBDA_EXEC_WRAPPER = /opt/python/bin/elasticapm-lambda # use this exact fixed value +ELASTIC_APM_LAMBDA_APM_SERVER = # this is your APM Server URL +ELASTIC_APM_SECRET_TOKEN = # this is your APM secret token +ELASTIC_APM_SEND_STRATEGY = background <1> ---- -- include::{apm-aws-lambda-root}/docs/images/images.asciidoc[tag=python-env-vars] -- -// end::console-extension-only[] +// end::console-with-agent[] -// tag::cli-extension-only[] +// tag::cli-with-agent[] To configure APM through the AWS command line interface execute the following command: [source,bash] ---- aws lambda update-function-configuration --function-name yourLambdaFunctionName \ - --environment "Variables={ELASTIC_APM_LAMBDA_APM_SERVER=,ELASTIC_APM_SECRET_TOKEN=,ELASTIC_APM_SEND_STRATEGY=background}" <1> + --environment "Variables={AWS_LAMBDA_EXEC_WRAPPER=/opt/python/bin/elasticapm-lambda,ELASTIC_APM_LAMBDA_APM_SERVER=,ELASTIC_APM_SECRET_TOKEN=,ELASTIC_APM_SEND_STRATEGY=background}" <1> ---- -// end::cli-extension-only[] +// end::cli-with-agent[] -// tag::sam-extension-only[] +// tag::sam-with-agent[] In your SAM `template.yml` file configure the following environment variables: @@ -46,15 +47,16 @@ Resources: ... Environment: Variables: + AWS_LAMBDA_EXEC_WRAPPER: /opt/python/bin/elasticapm-lambda ELASTIC_APM_LAMBDA_APM_SERVER: ELASTIC_APM_SECRET_TOKEN: ELASTIC_APM_SEND_STRATEGY: background <1> ... ---- -// end::sam-extension-only[] +// end::sam-with-agent[] -// tag::serverless-extension-only[] +// tag::serverless-with-agent[] In your `serverless.yml` file configure the following environment variables: @@ -65,15 +67,16 @@ functions: yourLambdaFunction: ... environment: + AWS_LAMBDA_EXEC_WRAPPER: /opt/python/bin/elasticapm-lambda ELASTIC_APM_LAMBDA_APM_SERVER: ELASTIC_APM_SECRET_TOKEN: ELASTIC_APM_SEND_STRATEGY: background <1> ... ---- -// end::serverless-extension-only[] +// end::serverless-with-agent[] -// tag::terraform-extension-only[] +// tag::terraform-with-agent[] In your Terraform file configure the following environment variables: [source,terraform] @@ -83,6 +86,7 @@ resource "aws_lambda_function" "your_lambda_function" { ... environment { variables = { + AWS_LAMBDA_EXEC_WRAPPER = /opt/python/bin/elasticapm-lambda ELASTIC_APM_LAMBDA_APM_SERVER = "" ELASTIC_APM_SECRET_TOKEN = "" ELASTIC_APM_SEND_STRATEGY = "background" <1> @@ -92,17 +96,18 @@ resource "aws_lambda_function" "your_lambda_function" { ... ---- -// end::terraform-extension-only[] +// end::terraform-with-agent[] -// tag::container-extension-only[] +// tag::container-with-agent[] Environment variables configured for an AWS Lambda function are passed to the container running the lambda function. You can use one of the other options (through AWS Web Console, AWS CLI, etc.) to configure the following environment variables: [source,bash] ---- +AWS_LAMBDA_EXEC_WRAPPER = /opt/python/bin/elasticapm-lambda # use this exact fixed value ELASTIC_APM_LAMBDA_APM_SERVER = # this is your APM Server URL ELASTIC_APM_SECRET_TOKEN = # this is your APM secret token ELASTIC_APM_SEND_STRATEGY = background <1> ---- -// end::container-extension-only[] +// end::container-with-agent[] diff --git a/docs/lambda/python-arn-replacement.asciidoc b/docs/lambda/python-arn-replacement.asciidoc new file mode 100644 index 000000000..24d9d1a7f --- /dev/null +++ b/docs/lambda/python-arn-replacement.asciidoc @@ -0,0 +1,9 @@ +++++ + +++++ \ No newline at end of file diff --git a/docs/serverless.asciidoc b/docs/serverless-lambda.asciidoc similarity index 54% rename from docs/serverless.asciidoc rename to docs/serverless-lambda.asciidoc index 47c869088..48c091390 100644 --- a/docs/serverless.asciidoc +++ b/docs/serverless-lambda.asciidoc @@ -1,10 +1,9 @@ [[lambda-support]] === Monitoring AWS Lambda Python Functions -:layer-section-type: extension-only +:layer-section-type: with-agent :apm-aws-repo-dir: ./lambda -Incorporating Elastic APM into your AWS Lambda functions is easy! -Follow the steps below to setup Elastic APM for your AWS Lambda Python functions. +The Python APM Agent can be used with AWS Lambda to monitor the execution of your AWS Lambda functions. [float] ==== Prerequisites @@ -12,58 +11,19 @@ Follow the steps below to setup Elastic APM for your AWS Lambda Python functions You need an APM Server to send APM data to. Follow the {apm-guide-ref}/apm-quick-start.html[APM Quick start] if you have not set one up yet. For the best-possible performance, we recommend setting up APM on {ecloud} in the same AWS region as your AWS Lambda functions. [float] -==== Step 1: Set up the {apm-lambda-ext} +==== Step 1: Select the AWS Region and Architecture include::{apm-aws-lambda-root}/docs/lambda-selector/lambda-attributes-selector.asciidoc[] -Add the {apm-lambda-ref}/aws-lambda-arch.html[{apm-lambda-ext}] as an https://docs.aws.amazon.com/lambda/latest/dg/invocation-layers.html[AWS Lambda Layer] to your AWS Lambda function. - -include::{apm-aws-lambda-root}/docs/lambda-selector/extension-arn-replacement.asciidoc[] -include::{apm-aws-lambda-root}/docs/add-extension/add-extension-layer-widget.asciidoc[] - [float] -==== Step 2: Set up the APM Python Agent - -You need to add `elastic-apm` as a dependency for your python function. -Depending on your deployment strategy, this could be as easy as adding -`elastic-apm` to your `requirements.txt` file, or installing it in the directory -you plan to deploy using pip: - -[source,bash] ----- -$ pip install -t elastic-apm ----- - -Note: Please use the latest version of the APM Python agent. A performance -issue was introduced in version 6.9.0 of the agent, and fixed in version 6.14.0. - -Once the library is included as a dependency in your function, you must -import the `capture_serverless` decorator and apply it to your handler: - -[source,python] ----- -from elasticapm import capture_serverless - -@capture_serverless -def handler(event, context): - return {"statusCode": r.status_code, "body": "Success!"} ----- - -Note: any database or connection pool setup should go inside of your handler, -otherwise the agent will not be able to instrument those objects and you may -see missing spans. Example: +==== Step 2: Add the APM Layers to your Lambda function +include::{apm-aws-lambda-root}/docs/lambda-selector/extension-arn-replacement.asciidoc[] +include::./lambda/python-arn-replacement.asciidoc[] -[source,python] ----- -conn = None +Both the {apm-lambda-ref}/aws-lambda-arch.html[{apm-lambda-ext}] and the Python APM Agent are added to your Lambda function as https://docs.aws.amazon.com/lambda/latest/dg/invocation-layers.html[AWS Lambda Layers]. Therefore, you need to add the corresponding Layer ARNs (identifiers) to your Lambda function. -@capture_serverless -def handler(event, context): - global conn - if not conn: - conn = pymysql.connect(host=rds_host, user=name, passwd=password, db=db_name, connect_timeout=5) ----- +include::{apm-aws-lambda-root}/docs/add-extension/add-extension-layer-widget.asciidoc[] [float] ==== Step 3: Configure APM on AWS Lambda @@ -80,8 +40,9 @@ include::./lambda/configure-lambda-widget.asciidoc[] You can optionally <> or the {apm-lambda-ref}/aws-lambda-config-options.html[configuration of the {apm-lambda-ext}]. -That's it; Once the agent is installed and working, spans will be captured for +That's it. After following the steps above, you're ready to go! Your Lambda +function invocations should be traced from now on. Spans will be captured for <>. You can also use -<> to capture custom spans, and -you can retrieve the `Client` object for capturing exceptions/messages -using <>. +<> to capture custom spans, and you can +retrieve the `Client` object for capturing exceptions/messages using +<>. diff --git a/docs/set-up.asciidoc b/docs/set-up.asciidoc index d74d06877..a49ea03bb 100644 --- a/docs/set-up.asciidoc +++ b/docs/set-up.asciidoc @@ -10,6 +10,7 @@ To get you off the ground, we’ve prepared guides for setting up the Agent with * <> * <> * <> + * <> * <> For custom instrumentation, see <>. @@ -26,7 +27,7 @@ include::./starlette.asciidoc[] include::./sanic.asciidoc[] -include::./serverless.asciidoc[] +include::./serverless-lambda.asciidoc[] include::./serverless-azure-functions.asciidoc[]