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" 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/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/dev-utils/make-distribution.sh b/dev-utils/make-distribution.sh new file mode 100755 index 000000000..87d37ba63 --- /dev/null +++ b/dev-utils/make-distribution.sh @@ -0,0 +1,58 @@ +#!/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 -f requirements.txt +rm -rf package +mkdir package +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 ./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/ + +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'" 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 diff --git a/elasticapm/contrib/serverless/aws.py b/elasticapm/contrib/serverless/aws.py index a17f8a886..dc9ae630e 100644 --- a/elasticapm/contrib/serverless/aws.py +++ b/elasticapm/contrib/serverless/aws.py @@ -85,19 +85,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() @@ -109,9 +97,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 = {}, {} @@ -125,6 +113,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/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. diff --git a/elasticapm/contrib/serverless/aws_wrapper/__init__.py b/elasticapm/contrib/serverless/aws_wrapper/__init__.py new file mode 100644 index 000000000..60a0f22ee --- /dev/null +++ b/elasticapm/contrib/serverless/aws_wrapper/__init__.py @@ -0,0 +1,29 @@ +# 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. diff --git a/elasticapm/contrib/serverless/aws_wrapper/elasticapm-lambda.py b/elasticapm/contrib/serverless/aws_wrapper/elasticapm-lambda.py new file mode 100644 index 000000000..5bbaa99be --- /dev/null +++ b/elasticapm/contrib/serverless/aws_wrapper/elasticapm-lambda.py @@ -0,0 +1,60 @@ +#!/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 os +import shutil +import sys + + +class LambdaError(Exception): + pass + + +if __name__ == "__main__": + 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" + + # Invoke the runtime + args = sys.argv[1:] + runtime = shutil.which(args[0]) + args = args[1:] + os.execl(runtime, runtime, *args) diff --git a/elasticapm/contrib/serverless/aws_wrapper/elasticapm_handler.py b/elasticapm/contrib/serverless/aws_wrapper/elasticapm_handler.py new file mode 100644 index 000000000..685de1901 --- /dev/null +++ b/elasticapm/contrib/serverless/aws_wrapper/elasticapm_handler.py @@ -0,0 +1,85 @@ +# 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") + +# 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: + 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): + 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(module.replace("/", ".")) + wrapped = getattr(module, handler) + + client = get_client() + + # 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)