From d9c30233dffaa33fbb513d4efc2aa077b4a4bf7d Mon Sep 17 00:00:00 2001 From: Colton Myers Date: Wed, 5 Apr 2023 12:20:06 -0600 Subject: [PATCH 01/16] Add lambda instrumentation + wrapper --- elasticapm/contrib/serverless/aws.py | 39 +++++++---- .../packages/lambda/__init__.py | 68 +++++++++++++++++++ .../packages/lambda/elasticapm-run | 11 +++ 3 files changed, 103 insertions(+), 15 deletions(-) create mode 100644 elasticapm/instrumentation/packages/lambda/__init__.py create mode 100644 elasticapm/instrumentation/packages/lambda/elasticapm-run diff --git a/elasticapm/contrib/serverless/aws.py b/elasticapm/contrib/serverless/aws.py index 786f61ffe..5606c4de6 100644 --- a/elasticapm/contrib/serverless/aws.py +++ b/elasticapm/contrib/serverless/aws.py @@ -82,19 +82,7 @@ def handler(event, context): name = kwargs.pop("name", None) - # Disable all background threads except for transport - kwargs["metrics_interval"] = "0ms" - kwargs["breakdown_metrics"] = False - if "metrics_sets" not in kwargs and "ELASTIC_APM_METRICS_SETS" not in os.environ: - # Allow users to override metrics sets - kwargs["metrics_sets"] = [] - kwargs["central_config"] = False - kwargs["cloud_provider"] = "none" - kwargs["framework_name"] = "AWS Lambda" - if "service_name" not in kwargs and "ELASTIC_APM_SERVICE_NAME" not in os.environ: - kwargs["service_name"] = os.environ["AWS_LAMBDA_FUNCTION_NAME"] - if "service_version" not in kwargs and "ELASTIC_APM_SERVICE_VERSION" not in os.environ: - kwargs["service_version"] = os.environ.get("AWS_LAMBDA_FUNCTION_VERSION") + kwargs = prep_kwargs(kwargs) global INSTRUMENTED client = get_client() @@ -106,9 +94,9 @@ def handler(event, context): @functools.wraps(func) def decorated(*args, **kwds): - if len(args) == 2: + if len(args) >= 2: # Saving these for request context later - event, context = args + event, context = args[0:2] else: event, context = {}, {} @@ -122,6 +110,27 @@ def decorated(*args, **kwds): return decorated +def prep_kwargs(kwargs=None): + if kwargs is None: + kwargs = {} + + # Disable all background threads except for transport + kwargs["metrics_interval"] = "0ms" + kwargs["breakdown_metrics"] = False + if "metrics_sets" not in kwargs and "ELASTIC_APM_METRICS_SETS" not in os.environ: + # Allow users to override metrics sets + kwargs["metrics_sets"] = [] + kwargs["central_config"] = False + kwargs["cloud_provider"] = "none" + kwargs["framework_name"] = "AWS Lambda" + if "service_name" not in kwargs and "ELASTIC_APM_SERVICE_NAME" not in os.environ: + kwargs["service_name"] = os.environ["AWS_LAMBDA_FUNCTION_NAME"] + if "service_version" not in kwargs and "ELASTIC_APM_SERVICE_VERSION" not in os.environ: + kwargs["service_version"] = os.environ.get("AWS_LAMBDA_FUNCTION_VERSION") + + return kwargs + + class _lambda_transaction(object): """ Context manager for creating transactions around AWS Lambda functions. diff --git a/elasticapm/instrumentation/packages/lambda/__init__.py b/elasticapm/instrumentation/packages/lambda/__init__.py new file mode 100644 index 000000000..b781a808e --- /dev/null +++ b/elasticapm/instrumentation/packages/lambda/__init__.py @@ -0,0 +1,68 @@ +# BSD 3-Clause License +# +# Copyright (c) 2023, Elasticsearch BV +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import os + +from elasticapm import Client, get_client +from elasticapm.contrib.serverless.aws import _lambda_transaction, prep_kwargs +from elasticapm.instrumentation.packages.base import AbstractInstrumentedModule +from elasticapm.utils.logging import get_logger + +logger = get_logger("elasticapm.instrument") + + +class LambdaInstrumentation(AbstractInstrumentedModule): + name = "lambda" + + creates_transactions = True + + def get_instrument_list(self): + handler = os.environ.get("_HANDLER", None) + if handler: + handler = handler.rsplit(".", 1) + return [handler] + logger.debug(f"Lambda instrumentation failed: no handler found. _HANDLER: {handler}") + return [] + + def call(self, module, method, wrapped, instance, args, kwargs): + client_kwargs = prep_kwargs() + client = get_client() + if not client: + client = Client(**client_kwargs) + if len(args) >= 2: + event, context = args[0:2] + else: + event, context = {}, {} + if not client.config.debug and client.config.instrument and client.config.enabled: + with _lambda_transaction(wrapped, None, client, event, context) as sls: + sls.response = wrapped(*args, **kwargs) + return sls.response + else: + return wrapped(*args, **kwargs) diff --git a/elasticapm/instrumentation/packages/lambda/elasticapm-run b/elasticapm/instrumentation/packages/lambda/elasticapm-run new file mode 100644 index 000000000..98725c37f --- /dev/null +++ b/elasticapm/instrumentation/packages/lambda/elasticapm-run @@ -0,0 +1,11 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import re +import sys + +from elasticapm.instrumentation.wrapper import setup + +if __name__ == "__main__": + sys.argv[0] = re.sub(r"(-script\.pyw|\.exe)?$", "", sys.argv[0]) + sys.exit(setup()) From 56477c544081390ccec0dd15a2658f8b160172c3 Mon Sep 17 00:00:00 2001 From: Colton Myers Date: Wed, 5 Apr 2023 12:24:03 -0600 Subject: [PATCH 02/16] Add new instrumentation to register --- elasticapm/instrumentation/register.py | 1 + 1 file changed, 1 insertion(+) diff --git a/elasticapm/instrumentation/register.py b/elasticapm/instrumentation/register.py index 43b263ec8..a30f19888 100644 --- a/elasticapm/instrumentation/register.py +++ b/elasticapm/instrumentation/register.py @@ -99,6 +99,7 @@ _wrapper_register = { "elasticapm.instrumentation.packages.flask.FlaskInstrumentation", "elasticapm.instrumentation.packages.django.DjangoAutoInstrumentation", + "elasticapm.instrumentation.packages.lambda.LambdaInstrumentation", } From 1de219b1d2a9dd4a020aabda8a47545f0546ac5c Mon Sep 17 00:00:00 2001 From: Colton Myers Date: Thu, 6 Apr 2023 12:42:42 -0600 Subject: [PATCH 03/16] Add python path modification --- elasticapm/instrumentation/packages/lambda/elasticapm-run | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/elasticapm/instrumentation/packages/lambda/elasticapm-run b/elasticapm/instrumentation/packages/lambda/elasticapm-run index 98725c37f..aca3829c5 100644 --- a/elasticapm/instrumentation/packages/lambda/elasticapm-run +++ b/elasticapm/instrumentation/packages/lambda/elasticapm-run @@ -4,7 +4,9 @@ import re import sys -from elasticapm.instrumentation.wrapper import setup +sys.path.insert(0, "/opt/python") + +from elasticapm.instrumentation.wrapper import setup # noqa if __name__ == "__main__": sys.argv[0] = re.sub(r"(-script\.pyw|\.exe)?$", "", sys.argv[0]) From 69de41ba2b2071c7150a13c5395b414181434e49 Mon Sep 17 00:00:00 2001 From: Colton Myers Date: Thu, 6 Apr 2023 12:44:46 -0600 Subject: [PATCH 04/16] Move elasticapm-run to elasticapm-run.py --- .../packages/lambda/elasticapm-run | 13 ------ .../packages/lambda/elasticapm-run.py | 43 +++++++++++++++++++ 2 files changed, 43 insertions(+), 13 deletions(-) delete mode 100644 elasticapm/instrumentation/packages/lambda/elasticapm-run create mode 100644 elasticapm/instrumentation/packages/lambda/elasticapm-run.py diff --git a/elasticapm/instrumentation/packages/lambda/elasticapm-run b/elasticapm/instrumentation/packages/lambda/elasticapm-run deleted file mode 100644 index aca3829c5..000000000 --- a/elasticapm/instrumentation/packages/lambda/elasticapm-run +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -import re -import sys - -sys.path.insert(0, "/opt/python") - -from elasticapm.instrumentation.wrapper import setup # noqa - -if __name__ == "__main__": - sys.argv[0] = re.sub(r"(-script\.pyw|\.exe)?$", "", sys.argv[0]) - sys.exit(setup()) diff --git a/elasticapm/instrumentation/packages/lambda/elasticapm-run.py b/elasticapm/instrumentation/packages/lambda/elasticapm-run.py new file mode 100644 index 000000000..25b8a13e8 --- /dev/null +++ b/elasticapm/instrumentation/packages/lambda/elasticapm-run.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# BSD 3-Clause License +# +# Copyright (c) 2023, Elasticsearch BV +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import re +import sys + +sys.path.insert(0, "/opt/python") + +from elasticapm.instrumentation.wrapper import setup # noqa + +if __name__ == "__main__": + sys.argv[0] = re.sub(r"(-script\.pyw|\.exe)?$", "", sys.argv[0]) + sys.exit(setup()) From b67b8c96769e358b6ed3e308391293d44efe71cd Mon Sep 17 00:00:00 2001 From: Colton Myers Date: Mon, 10 Apr 2023 13:17:00 -0600 Subject: [PATCH 05/16] Add new wrapper for lambda --- .../packages/lambda/elasticapm-run.py | 21 +++-- .../packages/lambda/elasticapm_handler.py | 84 +++++++++++++++++++ elasticapm/instrumentation/register.py | 1 - 3 files changed, 99 insertions(+), 7 deletions(-) create mode 100644 elasticapm/instrumentation/packages/lambda/elasticapm_handler.py diff --git a/elasticapm/instrumentation/packages/lambda/elasticapm-run.py b/elasticapm/instrumentation/packages/lambda/elasticapm-run.py index 25b8a13e8..dbc829331 100644 --- a/elasticapm/instrumentation/packages/lambda/elasticapm-run.py +++ b/elasticapm/instrumentation/packages/lambda/elasticapm-run.py @@ -31,13 +31,22 @@ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -import re -import sys +import os -sys.path.insert(0, "/opt/python") -from elasticapm.instrumentation.wrapper import setup # noqa +class LambdaError(Exception): + pass + if __name__ == "__main__": - sys.argv[0] = re.sub(r"(-script\.pyw|\.exe)?$", "", sys.argv[0]) - sys.exit(setup()) + original_handler = os.environ.get("_HANDLER", None) + if not original_handler: + raise LambdaError("Cannot find original handler. _HANDLER is not set correctly.") + + # AWS Lambda's `/var/runtime/bootstrap.py` uses `imp.load_module` to load + # the handler from "_HANDLER". This means that the handler will be reloaded + # (even if it's already been loaded), and any instrumentation that we do + # will be lost. Thus, we can't use our normal wrapper script, and must + # replace the handler altogether and wrap it manually. + os.environ["ELASTICAPM_ORIGINAL_HANDLER"] = original_handler + os.environ["_HANDLER"] = "elasticapm_handler.lambda_handler" diff --git a/elasticapm/instrumentation/packages/lambda/elasticapm_handler.py b/elasticapm/instrumentation/packages/lambda/elasticapm_handler.py new file mode 100644 index 000000000..a5b39ef0f --- /dev/null +++ b/elasticapm/instrumentation/packages/lambda/elasticapm_handler.py @@ -0,0 +1,84 @@ +# BSD 3-Clause License +# +# Copyright (c) 2023, Elasticsearch BV +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import os +from importlib import import_module + +import elasticapm +from elasticapm import Client, get_client +from elasticapm.contrib.serverless.aws import _lambda_transaction, prep_kwargs +from elasticapm.utils.logging import get_logger + +logger = get_logger("elasticapm.lambda") + +INSTRUMENTED = False + + +class LambdaError(Exception): + pass + + +def lambda_handler(event, context): + """ + This handler is designed to replace the default handler in the lambda + function, and then call the actual handler, which will be stored in + ELASTICAPM_ORIGINAL_HANDLER. + """ + # Prep original handler + original_handler = os.environ.get("ELASTICAPM_ORIGINAL_HANDLER", None) + if not original_handler: + raise LambdaError("Cannot find original handler. ELASTICAPM_ORIGINAL_HANDLER is not set correctly.") + try: + module, handler = original_handler.rsplit(".", 1) + except ValueError: + raise LambdaError(f"ELASTICAPM_ORIGINAL_HANDLER is not set correctly: {original_handler}") + + # Import handler + module = import_module(".".join(module.split("/"))) + wrapped = getattr(module, handler) + + # Prep client and instrument + client_kwargs = prep_kwargs() + client = get_client() + if not client: + client = Client(**client_kwargs) + client.activation_method = "wrapper" + global INSTRUMENTED + if not client.config.debug and client.config.instrument and client.config.enabled and not INSTRUMENTED: + elasticapm.instrument() + INSTRUMENTED = True + + # Run the handler + if not client.config.debug and client.config.instrument and client.config.enabled: + with _lambda_transaction(wrapped, None, client, event, context) as sls: + sls.response = wrapped(event, context) + return sls.response + else: + return wrapped(event, context) diff --git a/elasticapm/instrumentation/register.py b/elasticapm/instrumentation/register.py index a30f19888..43b263ec8 100644 --- a/elasticapm/instrumentation/register.py +++ b/elasticapm/instrumentation/register.py @@ -99,7 +99,6 @@ _wrapper_register = { "elasticapm.instrumentation.packages.flask.FlaskInstrumentation", "elasticapm.instrumentation.packages.django.DjangoAutoInstrumentation", - "elasticapm.instrumentation.packages.lambda.LambdaInstrumentation", } From 9cfdf0554ec3c44a919351e1fcf36721329f010c Mon Sep 17 00:00:00 2001 From: Colton Myers Date: Mon, 10 Apr 2023 13:32:38 -0600 Subject: [PATCH 06/16] execl the runtime --- .../instrumentation/packages/lambda/elasticapm-run.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/elasticapm/instrumentation/packages/lambda/elasticapm-run.py b/elasticapm/instrumentation/packages/lambda/elasticapm-run.py index dbc829331..5bbaa99be 100644 --- a/elasticapm/instrumentation/packages/lambda/elasticapm-run.py +++ b/elasticapm/instrumentation/packages/lambda/elasticapm-run.py @@ -32,6 +32,8 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import os +import shutil +import sys class LambdaError(Exception): @@ -50,3 +52,9 @@ class LambdaError(Exception): # replace the handler altogether and wrap it manually. os.environ["ELASTICAPM_ORIGINAL_HANDLER"] = original_handler os.environ["_HANDLER"] = "elasticapm_handler.lambda_handler" + + # Invoke the runtime + args = sys.argv[1:] + runtime = shutil.which(args[0]) + args = args[1:] + os.execl(runtime, runtime, *args) From 3bcfe8e22c8d378516308f2a4342f5f130c5d3dd Mon Sep 17 00:00:00 2001 From: Colton Myers Date: Tue, 11 Apr 2023 11:57:06 -0600 Subject: [PATCH 07/16] Move instrumentation to setup phase --- .../packages/lambda/elasticapm_handler.py | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/elasticapm/instrumentation/packages/lambda/elasticapm_handler.py b/elasticapm/instrumentation/packages/lambda/elasticapm_handler.py index a5b39ef0f..4e705e91e 100644 --- a/elasticapm/instrumentation/packages/lambda/elasticapm_handler.py +++ b/elasticapm/instrumentation/packages/lambda/elasticapm_handler.py @@ -38,7 +38,14 @@ logger = get_logger("elasticapm.lambda") -INSTRUMENTED = False +# Prep client and instrument +client_kwargs = prep_kwargs() +client = get_client() +if not client: + client = Client(**client_kwargs) +client.activation_method = "wrapper" +if not client.config.debug and client.config.instrument and client.config.enabled: + elasticapm.instrument() class LambdaError(Exception): @@ -64,16 +71,7 @@ def lambda_handler(event, context): module = import_module(".".join(module.split("/"))) wrapped = getattr(module, handler) - # Prep client and instrument - client_kwargs = prep_kwargs() client = get_client() - if not client: - client = Client(**client_kwargs) - client.activation_method = "wrapper" - global INSTRUMENTED - if not client.config.debug and client.config.instrument and client.config.enabled and not INSTRUMENTED: - elasticapm.instrument() - INSTRUMENTED = True # Run the handler if not client.config.debug and client.config.instrument and client.config.enabled: From 8ed332aa4fc0c5c257ed9a657f6881a0df80473b Mon Sep 17 00:00:00 2001 From: Colton Myers Date: Tue, 18 Apr 2023 13:47:43 -0600 Subject: [PATCH 08/16] Add explanation for import-time instrumentation --- .../instrumentation/packages/lambda/elasticapm_handler.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/elasticapm/instrumentation/packages/lambda/elasticapm_handler.py b/elasticapm/instrumentation/packages/lambda/elasticapm_handler.py index 4e705e91e..d265cd8e6 100644 --- a/elasticapm/instrumentation/packages/lambda/elasticapm_handler.py +++ b/elasticapm/instrumentation/packages/lambda/elasticapm_handler.py @@ -39,6 +39,9 @@ logger = get_logger("elasticapm.lambda") # Prep client and instrument +# For some reason, if we instrument as part of our handler, it adds 3+ seconds +# to the cold start time. So we do it here. I still don't know why this slowdown +# happens. client_kwargs = prep_kwargs() client = get_client() if not client: From 001eed32b96065ca17155c599b73882a4eb4cfbb Mon Sep 17 00:00:00 2001 From: Colton Myers Date: Tue, 25 Apr 2023 15:17:42 -0600 Subject: [PATCH 09/16] Move lambda wrapper stuff to contrib --- .../serverless/aws_wrapper}/__init__.py | 39 ------------------- .../serverless/aws_wrapper}/elasticapm-run.py | 0 .../aws_wrapper}/elasticapm_handler.py | 0 3 files changed, 39 deletions(-) rename elasticapm/{instrumentation/packages/lambda => contrib/serverless/aws_wrapper}/__init__.py (53%) rename elasticapm/{instrumentation/packages/lambda => contrib/serverless/aws_wrapper}/elasticapm-run.py (100%) rename elasticapm/{instrumentation/packages/lambda => contrib/serverless/aws_wrapper}/elasticapm_handler.py (100%) diff --git a/elasticapm/instrumentation/packages/lambda/__init__.py b/elasticapm/contrib/serverless/aws_wrapper/__init__.py similarity index 53% rename from elasticapm/instrumentation/packages/lambda/__init__.py rename to elasticapm/contrib/serverless/aws_wrapper/__init__.py index b781a808e..60a0f22ee 100644 --- a/elasticapm/instrumentation/packages/lambda/__init__.py +++ b/elasticapm/contrib/serverless/aws_wrapper/__init__.py @@ -27,42 +27,3 @@ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -import os - -from elasticapm import Client, get_client -from elasticapm.contrib.serverless.aws import _lambda_transaction, prep_kwargs -from elasticapm.instrumentation.packages.base import AbstractInstrumentedModule -from elasticapm.utils.logging import get_logger - -logger = get_logger("elasticapm.instrument") - - -class LambdaInstrumentation(AbstractInstrumentedModule): - name = "lambda" - - creates_transactions = True - - def get_instrument_list(self): - handler = os.environ.get("_HANDLER", None) - if handler: - handler = handler.rsplit(".", 1) - return [handler] - logger.debug(f"Lambda instrumentation failed: no handler found. _HANDLER: {handler}") - return [] - - def call(self, module, method, wrapped, instance, args, kwargs): - client_kwargs = prep_kwargs() - client = get_client() - if not client: - client = Client(**client_kwargs) - if len(args) >= 2: - event, context = args[0:2] - else: - event, context = {}, {} - if not client.config.debug and client.config.instrument and client.config.enabled: - with _lambda_transaction(wrapped, None, client, event, context) as sls: - sls.response = wrapped(*args, **kwargs) - return sls.response - else: - return wrapped(*args, **kwargs) diff --git a/elasticapm/instrumentation/packages/lambda/elasticapm-run.py b/elasticapm/contrib/serverless/aws_wrapper/elasticapm-run.py similarity index 100% rename from elasticapm/instrumentation/packages/lambda/elasticapm-run.py rename to elasticapm/contrib/serverless/aws_wrapper/elasticapm-run.py diff --git a/elasticapm/instrumentation/packages/lambda/elasticapm_handler.py b/elasticapm/contrib/serverless/aws_wrapper/elasticapm_handler.py similarity index 100% rename from elasticapm/instrumentation/packages/lambda/elasticapm_handler.py rename to elasticapm/contrib/serverless/aws_wrapper/elasticapm_handler.py From b8a6ef16669299b0928d599031f120ab62467169 Mon Sep 17 00:00:00 2001 From: Colton Myers Date: Tue, 25 Apr 2023 15:38:00 -0600 Subject: [PATCH 10/16] Add NOTICE.md for lambda layer --- LICENSE | 2 +- NOTICE.md | 404 +++--------------- .../contrib/serverless/aws_wrapper/NOTICE.md | 92 ++++ 3 files changed, 160 insertions(+), 338 deletions(-) create mode 100644 elasticapm/contrib/serverless/aws_wrapper/NOTICE.md diff --git a/LICENSE b/LICENSE index 13aa95719..05983284f 100644 --- a/LICENSE +++ b/LICENSE @@ -1,7 +1,7 @@ BSD 3-Clause License Copyright (c) 2009-2012, David Cramer and individual contributors -Copyright (c) 2013-2018, Elasticsearch BV +Copyright (c) 2013-2023, Elasticsearch BV All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/NOTICE.md b/NOTICE.md index 34c44c358..e72e5e858 100644 --- a/NOTICE.md +++ b/NOTICE.md @@ -1,360 +1,90 @@ # Notice -## Vendored dependencies - -This project contains dependencies which have been vendored. +## Dependencies installed by package management ### wrapt -- **path:** [`elasticapm/utils/wrapt`](elasticapm/utils/wrapt) -- **author:** Graham Dumpleton -- **project url:** https://github.com/GrahamDumpleton/wrapt -- **license:** BSD-2-Clause, http://opensource.org/licenses/BSD-2-Clause +- **author:** Graham Dumpleton +- **project url:** https://github.com/GrahamDumpleton/wrapt +- **license:** BSD-2-Clause, http://opensource.org/licenses/BSD-2-Clause - Copyright (c) 2013, Graham Dumpleton - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. + Copyright (c) 2013, Graham Dumpleton + All rights reserved. -## Dependencies installed by package management + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: -### urllib3 + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. -- **author:** Andrey Petrov -- **project url:** https://github.com/urllib3/urllib3 -- **license:** MIT License, https://opensource.org/licenses/MIT + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. - MIT License - - Copyright (c) 2008-2019 Andrey Petrov and contributors (see CONTRIBUTORS.txt) - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. -### certifi +### urllib3 -- **author:** Kenneth Reitz -- **project url:** https://github.com/certifi/python-certifi -- **license:** Mozilla Public License 2.0, https://opensource.org/licenses/MPL-2.0 +- **author:** Andrey Petrov +- **project url:** https://github.com/urllib3/urllib3 +- **license:** MIT License, https://opensource.org/licenses/MIT - This packge contains a modified version of ca-bundle.crt: - - ca-bundle.crt -- Bundle of CA Root Certificates - - Certificate data from Mozilla as of: Thu Nov 3 19:04:19 2011# - This is a bundle of X.509 certificates of public Certificate Authorities - (CA). These were automatically extracted from Mozilla's root certificates - file (certdata.txt). This file can be found in the mozilla source tree: - http://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt?raw=1# - It contains the certificates in PEM format and therefore - can be directly used with curl / libcurl / php_curl, or with - an Apache+mod_ssl webserver for SSL client authentication. - Just configure this file as the SSLCACertificateFile.# - - ***** BEGIN LICENSE BLOCK ***** - This Source Code Form is subject to the terms of the Mozilla Public License, - v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain - one at http://mozilla.org/MPL/2.0/. - - ***** END LICENSE BLOCK ***** - @(#) $RCSfile: certdata.txt,v $ $Revision: 1.80 $ $Date: 2011/11/03 15:11:58 $ + MIT License + Copyright (c) 2008-2019 Andrey Petrov and contributors (see CONTRIBUTORS.txt) -### cachetools + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: -- **author:** Thomas Kemmer -- **project url:** https://github.com/tkem/cachetools -- **license:** MIT License, https://opensource.org/licenses/MIT + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. - The MIT License (MIT) - - Copyright (c) 2014-2019 Thomas Kemmer - - Permission is hereby granted, free of charge, to any person obtaining a copy of - this software and associated documentation files (the "Software"), to deal in - the Software without restriction, including without limitation the rights to - use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - the Software, and to permit persons to whom the Software is furnished to do so, - subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + +### certifi +- **author:** Kenneth Reitz +- **project url:** https://github.com/certifi/python-certifi +- **license:** Mozilla Public License 2.0, https://opensource.org/licenses/MPL-2.0 -### blinker + This packge contains a modified version of ca-bundle.crt: + ca-bundle.crt -- Bundle of CA Root Certificates -- **author:** Jason Kirtland -- **project url:** https://github.com/jek/blinker -- **license:** MIT License, https://opensource.org/licenses/MIT + Certificate data from Mozilla as of: Thu Nov 3 19:04:19 2011# + This is a bundle of X.509 certificates of public Certificate Authorities + (CA). These were automatically extracted from Mozilla's root certificates + file (certdata.txt). This file can be found in the mozilla source tree: + http://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt?raw=1# + It contains the certificates in PEM format and therefore + can be directly used with curl / libcurl / php_curl, or with + an Apache+mod_ssl webserver for SSL client authentication. + Just configure this file as the SSLCACertificateFile.# - Copyright (c) The Blinker authors and contributors - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -### opentracing + ***** BEGIN LICENSE BLOCK ***** + This Source Code Form is subject to the terms of the Mozilla Public License, + v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain + one at http://mozilla.org/MPL/2.0/. -- **author:** The OpenTracing Authors -- **project url:** https://github.com/opentracing/opentracing-python -- **license:** Apache License, Version 2.0, https://opensource.org/licenses/Apache-2.0 - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright The OpenTracing Authors - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + ***** END LICENSE BLOCK ***** + @(#) $RCSfile: certdata.txt,v $ $Revision: 1.80 $ $Date: 2011/11/03 15:11:58 $ diff --git a/elasticapm/contrib/serverless/aws_wrapper/NOTICE.md b/elasticapm/contrib/serverless/aws_wrapper/NOTICE.md new file mode 100644 index 000000000..30a6c7203 --- /dev/null +++ b/elasticapm/contrib/serverless/aws_wrapper/NOTICE.md @@ -0,0 +1,92 @@ +apm-agent-python Copyright 2013-2023 Elasticsearch BV + +# Notice + +This lambda layer contains several dependencies which have been vendored. + +## urllib3 + +- **author:** Andrey Petrov +- **project url:** https://github.com/urllib3/urllib3 +- **license:** MIT License, https://opensource.org/licenses/MIT + + MIT License + + Copyright (c) 2008-2019 Andrey Petrov and contributors (see CONTRIBUTORS.txt) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + +## certifi + +- **author:** Kenneth Reitz +- **project url:** https://github.com/certifi/python-certifi +- **license:** Mozilla Public License 2.0, https://opensource.org/licenses/MPL-2.0 + + This packge contains a modified version of ca-bundle.crt: + + ca-bundle.crt -- Bundle of CA Root Certificates + + Certificate data from Mozilla as of: Thu Nov 3 19:04:19 2011# + This is a bundle of X.509 certificates of public Certificate Authorities + (CA). These were automatically extracted from Mozilla's root certificates + file (certdata.txt). This file can be found in the mozilla source tree: + http://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt?raw=1# + It contains the certificates in PEM format and therefore + can be directly used with curl / libcurl / php_curl, or with + an Apache+mod_ssl webserver for SSL client authentication. + Just configure this file as the SSLCACertificateFile.# + + ***** BEGIN LICENSE BLOCK ***** + This Source Code Form is subject to the terms of the Mozilla Public License, + v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain + one at http://mozilla.org/MPL/2.0/. + + ***** END LICENSE BLOCK ***** + @(#) $RCSfile: certdata.txt,v $ $Revision: 1.80 $ $Date: 2011/11/03 15:11:58 $ + +## wrapt + +- **author:** Graham Dumpleton +- **project url:** https://github.com/GrahamDumpleton/wrapt +- **license:** BSD-2-Clause, http://opensource.org/licenses/BSD-2-Clause + + Copyright (c) 2013, Graham Dumpleton + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. From ae194a4104b244556b4409febe02ab1b3546bf2c Mon Sep 17 00:00:00 2001 From: Colton Myers Date: Tue, 25 Apr 2023 16:08:15 -0600 Subject: [PATCH 11/16] Add make-distribution.sh (modified from Node-js version) --- dev-utils/make-distribution.sh | 55 ++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100755 dev-utils/make-distribution.sh diff --git a/dev-utils/make-distribution.sh b/dev-utils/make-distribution.sh new file mode 100755 index 000000000..d99df0e3b --- /dev/null +++ b/dev-utils/make-distribution.sh @@ -0,0 +1,55 @@ +#!/bin/bash +# +# Make a Python APM agent distribution that is used as follows: +# - "build/dist/elastic-apm-python-lambda-layer.zip" is published to AWS as a +# Lambda layer (https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html) +# - "build/dist/package/python/..." is used to build a Docker image of the APM agent +# + +if [ "$TRACE" != "" ]; then + export PS4='${BASH_SOURCE}:${LINENO}: ${FUNCNAME[0]:+${FUNCNAME[0]}(): }' + set -o xtrace +fi +set -o errexit +set -o pipefail + +# ---- support functions + +function fatal { + echo "$(basename $0): error: $*" + exit 1 +} + +# ---- mainline + +TOP=$(cd $(dirname $0)/../ >/dev/null; pwd) +BUILD_DIR="$TOP/build/dist" + +if ! command -v pip >/dev/null 2>&1; then + fatal "pip is unavailable" +fi + +rm -rf "$BUILD_DIR" +mkdir -p "$BUILD_DIR" +cd "$BUILD_DIR" + +rm -f elastic-apm-python-lambda-layer.zip +rm -rf package +mkdir package +pip install --target ./package/python "$TOP" +cd package +cp python/elasticapm/contrib/serverless/aws_wrapper/elasticapm-run.py ./elasticapm-run +chmod +x ./elasticapm-run +cp python/elasticapm/contrib/serverless/aws_wrapper/elasticapm_handler.py ./python/ +cp "$TOP/elasticapm/contrib/serverless/aws_wrapper/NOTICE.md" ./python/ + +echo "" +zip -q -r ../elastic-apm-python-lambda-layer.zip . +echo "Created build/dist/elastic-apm-python-lambda-layer.zip" + +cd .. + + +echo +echo "The lambda layer can be published as follows for dev work:" +echo " aws lambda --output json publish-layer-version --layer-name '$USER-dev-elastic-apm-python' --description '$USER dev Elastic APM Python agent lambda layer' --zip-file 'fileb://build/dist/elastic-apm-python-lambda-layer.zip'" From ee729e62c114d70053e1385119f09f877c6e1d34 Mon Sep 17 00:00:00 2001 From: Colton Myers Date: Tue, 25 Apr 2023 16:31:20 -0600 Subject: [PATCH 12/16] Pin the requirements --- dev-utils/make-distribution.sh | 5 ++++- dev-utils/requirements.txt | 4 ++++ 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 dev-utils/requirements.txt diff --git a/dev-utils/make-distribution.sh b/dev-utils/make-distribution.sh index d99df0e3b..8611d2e5f 100755 --- a/dev-utils/make-distribution.sh +++ b/dev-utils/make-distribution.sh @@ -34,9 +34,12 @@ mkdir -p "$BUILD_DIR" cd "$BUILD_DIR" rm -f elastic-apm-python-lambda-layer.zip +rm -f requirements.txt rm -rf package mkdir package -pip install --target ./package/python "$TOP" +cp "$TOP/dev-utils/requirements.txt" . +echo "$TOP" >> ./requirements.txt +pip install -r requirements.txt --target ./package/python cd package cp python/elasticapm/contrib/serverless/aws_wrapper/elasticapm-run.py ./elasticapm-run chmod +x ./elasticapm-run diff --git a/dev-utils/requirements.txt b/dev-utils/requirements.txt new file mode 100644 index 000000000..cdf7f37c0 --- /dev/null +++ b/dev-utils/requirements.txt @@ -0,0 +1,4 @@ +# These are the pinned requirements for the lambda layer/docker image +certifi==2022.12.7 +urllib3==1.26.15 +wrapt==1.15.0 From 9268410d8afcc034d553a4b0ef8dea75fc54569a Mon Sep 17 00:00:00 2001 From: Colton Myers Date: Tue, 25 Apr 2023 16:39:02 -0600 Subject: [PATCH 13/16] Add dependabot.yml --- .github/dependabot.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..8d3d736cb --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,12 @@ +--- +version: 2 +updates: + # Enable version updates for python + - package-ecosystem: "pip" + # Look for `requirements.txt` file in the `dev-utils` directory + directory: "/dev-utils/" + # Check for updates once a week + schedule: + interval: "weekly" + reviewers: + - "elastic/apm-agent-python" From 3217214c5475dc672de2413a3b421686459521e2 Mon Sep 17 00:00:00 2001 From: Colton Myers Date: Fri, 5 May 2023 12:38:22 -0600 Subject: [PATCH 14/16] Rename elasticapm-lambda + add elasticapm-run to package --- dev-utils/make-distribution.sh | 5 +++-- .../aws_wrapper/{elasticapm-run.py => elasticapm-lambda.py} | 0 2 files changed, 3 insertions(+), 2 deletions(-) rename elasticapm/contrib/serverless/aws_wrapper/{elasticapm-run.py => elasticapm-lambda.py} (100%) diff --git a/dev-utils/make-distribution.sh b/dev-utils/make-distribution.sh index 8611d2e5f..0e52f375d 100755 --- a/dev-utils/make-distribution.sh +++ b/dev-utils/make-distribution.sh @@ -41,8 +41,9 @@ cp "$TOP/dev-utils/requirements.txt" . echo "$TOP" >> ./requirements.txt pip install -r requirements.txt --target ./package/python cd package -cp python/elasticapm/contrib/serverless/aws_wrapper/elasticapm-run.py ./elasticapm-run -chmod +x ./elasticapm-run +cp python/elasticapm/contrib/serverless/aws_wrapper/elasticapm-lambda.py ./elasticapm-lambda +cp python/bin/elasticapm-run ./elasticapm-run +chmod +x ./elasticapm-* cp python/elasticapm/contrib/serverless/aws_wrapper/elasticapm_handler.py ./python/ cp "$TOP/elasticapm/contrib/serverless/aws_wrapper/NOTICE.md" ./python/ diff --git a/elasticapm/contrib/serverless/aws_wrapper/elasticapm-run.py b/elasticapm/contrib/serverless/aws_wrapper/elasticapm-lambda.py similarity index 100% rename from elasticapm/contrib/serverless/aws_wrapper/elasticapm-run.py rename to elasticapm/contrib/serverless/aws_wrapper/elasticapm-lambda.py From ae151424152782c61df3a98837a6b1a37213a1d1 Mon Sep 17 00:00:00 2001 From: Colton Myers Date: Fri, 5 May 2023 13:07:16 -0600 Subject: [PATCH 15/16] Add Dockerfile and put elasticapm-lambda in python/bin --- Dockerfile | 4 ++++ dev-utils/make-distribution.sh | 5 ++--- 2 files changed, 6 insertions(+), 3 deletions(-) create mode 100644 Dockerfile diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..a4752936a --- /dev/null +++ b/Dockerfile @@ -0,0 +1,4 @@ +# Pin to Alpine 3.17.3 +FROM alpine@sha256:124c7d2707904eea7431fffe91522a01e5a861a624ee31d03372cc1d138a3126 +ARG AGENT_DIR +COPY ${AGENT_DIR} /opt/python \ No newline at end of file diff --git a/dev-utils/make-distribution.sh b/dev-utils/make-distribution.sh index 0e52f375d..87d37ba63 100755 --- a/dev-utils/make-distribution.sh +++ b/dev-utils/make-distribution.sh @@ -41,9 +41,8 @@ cp "$TOP/dev-utils/requirements.txt" . echo "$TOP" >> ./requirements.txt pip install -r requirements.txt --target ./package/python cd package -cp python/elasticapm/contrib/serverless/aws_wrapper/elasticapm-lambda.py ./elasticapm-lambda -cp python/bin/elasticapm-run ./elasticapm-run -chmod +x ./elasticapm-* +cp python/elasticapm/contrib/serverless/aws_wrapper/elasticapm-lambda.py ./python/bin/elasticapm-lambda +chmod +x ./python/bin/elasticapm-lambda cp python/elasticapm/contrib/serverless/aws_wrapper/elasticapm_handler.py ./python/ cp "$TOP/elasticapm/contrib/serverless/aws_wrapper/NOTICE.md" ./python/ From 0c121bf115a3e4f442475b2be798458222776d48 Mon Sep 17 00:00:00 2001 From: Colton Myers Date: Tue, 9 May 2023 10:47:37 -0600 Subject: [PATCH 16/16] Update elasticapm/contrib/serverless/aws_wrapper/elasticapm_handler.py Co-authored-by: Benjamin Wohlwend --- elasticapm/contrib/serverless/aws_wrapper/elasticapm_handler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elasticapm/contrib/serverless/aws_wrapper/elasticapm_handler.py b/elasticapm/contrib/serverless/aws_wrapper/elasticapm_handler.py index d265cd8e6..685de1901 100644 --- a/elasticapm/contrib/serverless/aws_wrapper/elasticapm_handler.py +++ b/elasticapm/contrib/serverless/aws_wrapper/elasticapm_handler.py @@ -71,7 +71,7 @@ def lambda_handler(event, context): raise LambdaError(f"ELASTICAPM_ORIGINAL_HANDLER is not set correctly: {original_handler}") # Import handler - module = import_module(".".join(module.split("/"))) + module = import_module(module.replace("/", ".")) wrapped = getattr(module, handler) client = get_client()