From 838f3c578fb7ec4c5c805a0c929ecc28600beb8b Mon Sep 17 00:00:00 2001 From: heitorlessa Date: Fri, 10 Jun 2022 05:12:46 +0200 Subject: [PATCH 01/25] chore(governance): warn message on closed issues --- .github/workflows/on_closed_issues.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 .github/workflows/on_closed_issues.yml diff --git a/.github/workflows/on_closed_issues.yml b/.github/workflows/on_closed_issues.yml new file mode 100644 index 00000000000..4c3f9bc1780 --- /dev/null +++ b/.github/workflows/on_closed_issues.yml @@ -0,0 +1,12 @@ +name: Closed Issue Message +on: + issues: + types: [closed] +jobs: + auto_comment: + runs-on: ubuntu-latest + steps: + - uses: aws-actions/closed-issue-message@v1 + with: + repo-token: "${{ secrets.GITHUB_TOKEN }}" + message: "Comments on closed issues are hard for our team to see." From 02af1746ccca88c290188579131afd11d3721dfe Mon Sep 17 00:00:00 2001 From: heitorlessa Date: Thu, 23 Jun 2022 10:44:56 +0200 Subject: [PATCH 02/25] docs(tracer): split initial example --- docs/core/tracer.md | 25 +++---------------- examples/tracer/src/capture_lambda_handler.py | 15 +++++++++++ examples/tracer/template.yaml | 23 +++++++++++++++++ 3 files changed, 42 insertions(+), 21 deletions(-) create mode 100644 examples/tracer/src/capture_lambda_handler.py create mode 100644 examples/tracer/template.yaml diff --git a/docs/core/tracer.md b/docs/core/tracer.md index a773ecb52a8..963552c3e99 100644 --- a/docs/core/tracer.md +++ b/docs/core/tracer.md @@ -20,33 +20,16 @@ Tracer is an opinionated thin wrapper for [AWS X-Ray Python SDK](https://github. Before your use this utility, your AWS Lambda function [must have permissions](https://docs.aws.amazon.com/lambda/latest/dg/services-xray.html#services-xray-permissions) to send traces to AWS X-Ray. -```yaml hl_lines="6 9" title="AWS Serverless Application Model (SAM) example" -Resources: - HelloWorldFunction: - Type: AWS::Serverless::Function - Properties: - Runtime: python3.8 - Tracing: Active - Environment: - Variables: - POWERTOOLS_SERVICE_NAME: example +```yaml hl_lines="9 12" title="AWS Serverless Application Model (SAM) example" +--8<-- "examples/tracer/template.yaml" ``` ### Lambda handler You can quickly start by initializing `Tracer` and use `capture_lambda_handler` decorator for your Lambda handler. -```python hl_lines="1 3 6" title="Tracing Lambda handler with capture_lambda_handler" -from aws_lambda_powertools import Tracer - -tracer = Tracer() # Sets service via env var -# OR tracer = Tracer(service="example") - -@tracer.capture_lambda_handler -def handler(event, context): - charge_id = event.get('charge_id') - payment = collect_payment(charge_id) - ... +```python hl_lines="1 4 12" title="Tracing Lambda handler with capture_lambda_handler" +--8<-- "examples/tracer/src/capture_lambda_handler.py" ``` `capture_lambda_handler` performs these additional tasks to ease operations: diff --git a/examples/tracer/src/capture_lambda_handler.py b/examples/tracer/src/capture_lambda_handler.py new file mode 100644 index 00000000000..461a31cd213 --- /dev/null +++ b/examples/tracer/src/capture_lambda_handler.py @@ -0,0 +1,15 @@ +from aws_lambda_powertools import Tracer +from aws_lambda_powertools.utilities.typing import LambdaContext + +tracer = Tracer() # Sets service via POWERTOOLS_SERVICE_NAME env var +# OR tracer = Tracer(service="example") + + +def collect_payment(charge_id: str) -> str: + return f"dummy payment collected for charge: {charge_id}" + + +@tracer.capture_lambda_handler +def handler(event: dict, context: LambdaContext) -> str: + charge_id = event.get("charge_id") + return collect_payment(charge_id) diff --git a/examples/tracer/template.yaml b/examples/tracer/template.yaml new file mode 100644 index 00000000000..504661d634d --- /dev/null +++ b/examples/tracer/template.yaml @@ -0,0 +1,23 @@ +AWSTemplateFormatVersion: "2010-09-09" +Transform: AWS::Serverless-2016-10-31 +Description: AWS Lambda Powertools Tracer doc examples + +Globals: + Function: + Timeout: 5 + Runtime: python3.9 + Tracing: Active + Environment: + Variables: + POWERTOOLS_SERVICE_NAME: example + Layers: + # Find the latest Layer version in the official documentation + # https://awslabs.github.io/aws-lambda-powertools-python/latest/#lambda-layer + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPython:21 + +Resources: + CaptureLambdaHandlerExample: + Type: AWS::Serverless::Function + Properties: + CodeUri: src + Handler: capture_lambda_handler.handler From cb4470837035c529daeba99a8025d067a1595413 Mon Sep 17 00:00:00 2001 From: heitorlessa Date: Thu, 23 Jun 2022 10:46:06 +0200 Subject: [PATCH 03/25] chore(ci): rebuild doc to include examples' changes --- .github/workflows/python_docs.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/python_docs.yml b/.github/workflows/python_docs.yml index d168e1ae68a..7b842f038d6 100644 --- a/.github/workflows/python_docs.yml +++ b/.github/workflows/python_docs.yml @@ -8,6 +8,7 @@ on: - "docs/**" - "CHANGELOG.md" - "mkdocs.yml" + - "examples/**" jobs: docs: From 466c2bd6428ecea77458512b8e2c9b261aefcbcc Mon Sep 17 00:00:00 2001 From: heitorlessa Date: Thu, 23 Jun 2022 10:57:25 +0200 Subject: [PATCH 04/25] chore: add cfn-lint in pre-commit --- .pre-commit-config.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 97bdef15726..3107b1fe136 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -36,3 +36,8 @@ repos: hooks: - id: markdownlint args: ["--fix"] + - repo: https://github.com/aws-cloudformation/cfn-python-lint + rev: v0.61.1 + hooks: + - id: cfn-python-lint + files: examples/.*\.(yaml|yml)$ From ef1d90f99c4b83c139bccda056d2e59b4a5efcec Mon Sep 17 00:00:00 2001 From: heitorlessa Date: Thu, 23 Jun 2022 11:01:25 +0200 Subject: [PATCH 05/25] feat(ci): include examples folder in linting/fmt --- Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 5ad35546f95..6173e3e310d 100644 --- a/Makefile +++ b/Makefile @@ -10,11 +10,11 @@ dev: pre-commit install format: - poetry run isort aws_lambda_powertools tests - poetry run black aws_lambda_powertools tests + poetry run isort aws_lambda_powertools tests examples + poetry run black aws_lambda_powertools tests examples lint: format - poetry run flake8 aws_lambda_powertools/* tests/* + poetry run flake8 aws_lambda_powertools tests examples lint-docs: docker run -v ${PWD}:/markdown 06kellyjac/markdownlint-cli "docs" From 87bccfeb2cdb13886e4f4c63ae3291ed9c1f0a7f Mon Sep 17 00:00:00 2001 From: heitorlessa Date: Thu, 23 Jun 2022 11:19:42 +0200 Subject: [PATCH 06/25] fix(pre-commit): ensure flake8 includes examples --- .pre-commit-config.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3107b1fe136..8a614f78968 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -30,7 +30,6 @@ repos: entry: poetry run flake8 language: system types: [python] - exclude: example - repo: https://github.com/igorshubovych/markdownlint-cli rev: "11c08644ce6df850480d98f628596446a526cbc6" # frozen: v0.31.1 hooks: From 7f6ef84c56097d0c901b54589998ce1d551c2825 Mon Sep 17 00:00:00 2001 From: heitorlessa Date: Thu, 23 Jun 2022 13:12:20 +0200 Subject: [PATCH 07/25] feat(ci): include cfn-lint in docs workflow --- .github/workflows/python_docs.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/python_docs.yml b/.github/workflows/python_docs.yml index 7b842f038d6..3a6e15e5431 100644 --- a/.github/workflows/python_docs.yml +++ b/.github/workflows/python_docs.yml @@ -21,10 +21,15 @@ jobs: uses: actions/setup-python@v4 with: python-version: "3.8" + # Maintenance: temporarily until we drop Python 3.6 and make cfn-lint a dev dependency + - name: Setup Cloud Formation Linter with Latest Version + uses: scottbrenner/cfn-lint-action@v2 - name: Install dependencies run: make dev - name: Lint documentation - run: make lint-docs + run: | + make lint-docs + cfn-lint examples/**/*.yaml - name: Setup doc deploy run: | git config --global user.name Docs deploy From c28d715df92864bc8afee2580b404e2706781a10 Mon Sep 17 00:00:00 2001 From: heitorlessa Date: Thu, 23 Jun 2022 15:42:34 +0200 Subject: [PATCH 08/25] chore: move to approach B for multiple IaC --- examples/tracer/sam/.aws-sam/build.toml | 13 +++++++++++++ examples/tracer/{ => sam}/template.yaml | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 examples/tracer/sam/.aws-sam/build.toml rename examples/tracer/{ => sam}/template.yaml (96%) diff --git a/examples/tracer/sam/.aws-sam/build.toml b/examples/tracer/sam/.aws-sam/build.toml new file mode 100644 index 00000000000..abeca25b2e5 --- /dev/null +++ b/examples/tracer/sam/.aws-sam/build.toml @@ -0,0 +1,13 @@ +# This file is auto generated by SAM CLI build command + +[function_build_definitions] +[function_build_definitions.822b185b-39d9-48d0-962a-0e7cca6e0955] +codeuri = "/Users/lessa/DEV/aws-lambda-powertools-python/examples/tracer/src" +runtime = "python3.9" +architecture = "x86_64" +handler = "capture_lambda_handler.handler" +manifest_hash = "" +packagetype = "Zip" +functions = ["CaptureLambdaHandlerExample"] + +[layer_build_definitions] diff --git a/examples/tracer/template.yaml b/examples/tracer/sam/template.yaml similarity index 96% rename from examples/tracer/template.yaml rename to examples/tracer/sam/template.yaml index 504661d634d..11cee9be3a8 100644 --- a/examples/tracer/template.yaml +++ b/examples/tracer/sam/template.yaml @@ -19,5 +19,5 @@ Resources: CaptureLambdaHandlerExample: Type: AWS::Serverless::Function Properties: - CodeUri: src + CodeUri: ../src Handler: capture_lambda_handler.handler From 495e4ba3d01bec6635a3a9c2f442eb5626a7ee98 Mon Sep 17 00:00:00 2001 From: heitorlessa Date: Thu, 23 Jun 2022 15:52:36 +0200 Subject: [PATCH 09/25] chore: add sam build gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 5d28e3a615f..40687686d1d 100644 --- a/.gitignore +++ b/.gitignore @@ -306,3 +306,4 @@ site/ !docs/overrides/*.html !.github/workflows/lib +.aws-sam/* From 0252da61efa082733b58e213c1ab52f81b4853e4 Mon Sep 17 00:00:00 2001 From: heitorlessa Date: Thu, 23 Jun 2022 15:52:36 +0200 Subject: [PATCH 10/25] chore: add sam build gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 5d28e3a615f..40687686d1d 100644 --- a/.gitignore +++ b/.gitignore @@ -306,3 +306,4 @@ site/ !docs/overrides/*.html !.github/workflows/lib +.aws-sam/* From ab2ad8d1dc2d9f765f869b481fcc3aaa83e72bce Mon Sep 17 00:00:00 2001 From: heitorlessa Date: Thu, 23 Jun 2022 15:42:34 +0200 Subject: [PATCH 11/25] chore: move to approach B for multiple IaC --- examples/tracer/sam/template.yaml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 examples/tracer/sam/template.yaml diff --git a/examples/tracer/sam/template.yaml b/examples/tracer/sam/template.yaml new file mode 100644 index 00000000000..11cee9be3a8 --- /dev/null +++ b/examples/tracer/sam/template.yaml @@ -0,0 +1,23 @@ +AWSTemplateFormatVersion: "2010-09-09" +Transform: AWS::Serverless-2016-10-31 +Description: AWS Lambda Powertools Tracer doc examples + +Globals: + Function: + Timeout: 5 + Runtime: python3.9 + Tracing: Active + Environment: + Variables: + POWERTOOLS_SERVICE_NAME: example + Layers: + # Find the latest Layer version in the official documentation + # https://awslabs.github.io/aws-lambda-powertools-python/latest/#lambda-layer + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPython:21 + +Resources: + CaptureLambdaHandlerExample: + Type: AWS::Serverless::Function + Properties: + CodeUri: ../src + Handler: capture_lambda_handler.handler From 78d7b356b75e7a1fc8ded1180907375557a5d39b Mon Sep 17 00:00:00 2001 From: heitorlessa Date: Thu, 23 Jun 2022 15:59:10 +0200 Subject: [PATCH 12/25] chore: add sam build gitignore v2 --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 40687686d1d..b776e1999c2 100644 --- a/.gitignore +++ b/.gitignore @@ -306,4 +306,4 @@ site/ !docs/overrides/*.html !.github/workflows/lib -.aws-sam/* +examples/**/sam/.aws-sam From cc3743e2262532353a5a6d658b9d2eb011225faf Mon Sep 17 00:00:00 2001 From: heitorlessa Date: Thu, 23 Jun 2022 16:03:08 +0200 Subject: [PATCH 13/25] chore: remove build leftover --- examples/tracer/sam/.aws-sam/build.toml | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 examples/tracer/sam/.aws-sam/build.toml diff --git a/examples/tracer/sam/.aws-sam/build.toml b/examples/tracer/sam/.aws-sam/build.toml deleted file mode 100644 index abeca25b2e5..00000000000 --- a/examples/tracer/sam/.aws-sam/build.toml +++ /dev/null @@ -1,13 +0,0 @@ -# This file is auto generated by SAM CLI build command - -[function_build_definitions] -[function_build_definitions.822b185b-39d9-48d0-962a-0e7cca6e0955] -codeuri = "/Users/lessa/DEV/aws-lambda-powertools-python/examples/tracer/src" -runtime = "python3.9" -architecture = "x86_64" -handler = "capture_lambda_handler.handler" -manifest_hash = "" -packagetype = "Zip" -functions = ["CaptureLambdaHandlerExample"] - -[layer_build_definitions] From 8bd23499433552ef89d43d33b14ceb84d1494173 Mon Sep 17 00:00:00 2001 From: heitorlessa Date: Thu, 23 Jun 2022 16:16:15 +0200 Subject: [PATCH 14/25] docs(tracer): split annotations and metadata snippet --- docs/core/tracer.md | 21 ++++--------------- examples/tracer/src/capture_lambda_handler.py | 4 ++-- examples/tracer/src/put_trace_annotations.py | 15 +++++++++++++ examples/tracer/src/put_trace_metadata.py | 21 +++++++++++++++++++ 4 files changed, 42 insertions(+), 19 deletions(-) create mode 100644 examples/tracer/src/put_trace_annotations.py create mode 100644 examples/tracer/src/put_trace_metadata.py diff --git a/docs/core/tracer.md b/docs/core/tracer.md index 963552c3e99..63fa5cc80e2 100644 --- a/docs/core/tracer.md +++ b/docs/core/tracer.md @@ -42,27 +42,14 @@ You can quickly start by initializing `Tracer` and use `capture_lambda_handler` **Annotations** are key-values associated with traces and indexed by AWS X-Ray. You can use them to filter traces and to create [Trace Groups](https://aws.amazon.com/about-aws/whats-new/2018/11/aws-xray-adds-the-ability-to-group-traces/) to slice and dice your transactions. -```python hl_lines="7" title="Adding annotations with put_annotation method" -from aws_lambda_powertools import Tracer -tracer = Tracer() - -@tracer.capture_lambda_handler -def handler(event, context): - ... - tracer.put_annotation(key="PaymentStatus", value="SUCCESS") +```python hl_lines="8" title="Adding annotations with put_annotation method" +--8<-- "examples/tracer/src/put_trace_annotations.py" ``` **Metadata** are key-values also associated with traces but not indexed by AWS X-Ray. You can use them to add additional context for an operation using any native object. -```python hl_lines="8" title="Adding arbitrary metadata with put_metadata method" -from aws_lambda_powertools import Tracer -tracer = Tracer() - -@tracer.capture_lambda_handler -def handler(event, context): - ... - ret = some_logic() - tracer.put_metadata(key="payment_response", value=ret) +```python hl_lines="19" title="Adding arbitrary metadata with put_metadata method" +--8<-- "examples/tracer/src/put_trace_metadata.py" ``` ### Synchronous functions diff --git a/examples/tracer/src/capture_lambda_handler.py b/examples/tracer/src/capture_lambda_handler.py index 461a31cd213..f5d2c1efcea 100644 --- a/examples/tracer/src/capture_lambda_handler.py +++ b/examples/tracer/src/capture_lambda_handler.py @@ -11,5 +11,5 @@ def collect_payment(charge_id: str) -> str: @tracer.capture_lambda_handler def handler(event: dict, context: LambdaContext) -> str: - charge_id = event.get("charge_id") - return collect_payment(charge_id) + charge_id = event.get("charge_id", "") + return collect_payment(charge_id=charge_id) diff --git a/examples/tracer/src/put_trace_annotations.py b/examples/tracer/src/put_trace_annotations.py new file mode 100644 index 00000000000..0d9455c7acd --- /dev/null +++ b/examples/tracer/src/put_trace_annotations.py @@ -0,0 +1,15 @@ +from aws_lambda_powertools import Tracer +from aws_lambda_powertools.utilities.typing import LambdaContext + +tracer = Tracer() + + +def collect_payment(charge_id: str) -> str: + tracer.put_annotation(key="PaymentId", value=charge_id) + return f"dummy payment collected for charge: {charge_id}" + + +@tracer.capture_lambda_handler +def handler(event: dict, context: LambdaContext) -> str: + charge_id = event.get("charge_id", "") + return collect_payment(charge_id=charge_id) diff --git a/examples/tracer/src/put_trace_metadata.py b/examples/tracer/src/put_trace_metadata.py new file mode 100644 index 00000000000..23b6753677c --- /dev/null +++ b/examples/tracer/src/put_trace_metadata.py @@ -0,0 +1,21 @@ +from aws_lambda_powertools import Tracer +from aws_lambda_powertools.utilities.typing import LambdaContext + +tracer = Tracer() + + +def collect_payment(charge_id: str) -> str: + return f"dummy payment collected for charge: {charge_id}" + + +@tracer.capture_lambda_handler +def handler(event: dict, context: LambdaContext) -> str: + payment_context = { + "charge_id": event.get("charge_id", ""), + "merchant_id": event.get("merchant_id", ""), + "request_id": context.aws_request_id, + } + payment_context["receipt_id"] = collect_payment(charge_id=payment_context["charge_id"]) + tracer.put_metadata(key="payment_response", value=payment_context) + + return payment_context["receipt_id"] From 64d92d9ab09291845eae3b5eb281158521521d46 Mon Sep 17 00:00:00 2001 From: heitorlessa Date: Thu, 23 Jun 2022 16:20:08 +0200 Subject: [PATCH 15/25] docs(tracer): split synchronous fn snippet --- docs/core/tracer.md | 8 ++------ examples/tracer/src/capture_method.py | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 6 deletions(-) create mode 100644 examples/tracer/src/capture_method.py diff --git a/docs/core/tracer.md b/docs/core/tracer.md index 63fa5cc80e2..029c49fb766 100644 --- a/docs/core/tracer.md +++ b/docs/core/tracer.md @@ -56,12 +56,8 @@ You can quickly start by initializing `Tracer` and use `capture_lambda_handler` You can trace synchronous functions using the `capture_method` decorator. -```python hl_lines="7 13" title="Tracing an arbitrary function with capture_method" -@tracer.capture_method -def collect_payment(charge_id): - ret = requests.post(PAYMENT_ENDPOINT) # logic - tracer.put_annotation("PAYMENT_STATUS", "SUCCESS") # custom annotation - return ret +```python hl_lines="7" title="Tracing an arbitrary function with capture_method" +--8<-- "examples/tracer/src/capture_method.py" ``` ???+ note "Note: Function responses are auto-captured and stored as JSON, by default." diff --git a/examples/tracer/src/capture_method.py b/examples/tracer/src/capture_method.py new file mode 100644 index 00000000000..edf1ed719f4 --- /dev/null +++ b/examples/tracer/src/capture_method.py @@ -0,0 +1,16 @@ +from aws_lambda_powertools import Tracer +from aws_lambda_powertools.utilities.typing import LambdaContext + +tracer = Tracer() + + +@tracer.capture_method +def collect_payment(charge_id: str) -> str: + tracer.put_annotation(key="PaymentId", value=charge_id) + return f"dummy payment collected for charge: {charge_id}" + + +@tracer.capture_lambda_handler +def handler(event: dict, context: LambdaContext) -> str: + charge_id = event.get("charge_id", "") + return collect_payment(charge_id=charge_id) From c187c9e38395abd15c0db0b1fea722bb27e0c4b3 Mon Sep 17 00:00:00 2001 From: heitorlessa Date: Thu, 23 Jun 2022 16:53:38 +0200 Subject: [PATCH 16/25] docs(tracer): split async, ctx manager, and generator --- docs/core/tracer.md | 37 +++---------------- examples/tracer/src/capture_method_async.py | 19 ++++++++++ .../src/capture_method_context_manager.py | 27 ++++++++++++++ .../tracer/src/capture_method_generators.py | 17 +++++++++ 4 files changed, 68 insertions(+), 32 deletions(-) create mode 100644 examples/tracer/src/capture_method_async.py create mode 100644 examples/tracer/src/capture_method_context_manager.py create mode 100644 examples/tracer/src/capture_method_generators.py diff --git a/docs/core/tracer.md b/docs/core/tracer.md index 029c49fb766..d9875d3d24d 100644 --- a/docs/core/tracer.md +++ b/docs/core/tracer.md @@ -76,47 +76,20 @@ You can trace asynchronous functions and generator functions (including context === "Async" - ```python hl_lines="7" - import asyncio - import contextlib - from aws_lambda_powertools import Tracer - - tracer = Tracer() - - @tracer.capture_method - async def collect_payment(): - ... + ```python hl_lines="8" + --8<-- "examples/tracer/src/capture_method_async.py" ``` === "Context manager" - ```python hl_lines="7-8" - import asyncio - import contextlib - from aws_lambda_powertools import Tracer - - tracer = Tracer() - - @contextlib.contextmanager - @tracer.capture_method - def collect_payment_ctxman(): - yield result - ... + ```python hl_lines="12-13" + --8<-- "examples/tracer/src/capture_method_context_manager.py" ``` === "Generators" ```python hl_lines="9" - import asyncio - import contextlib - from aws_lambda_powertools import Tracer - - tracer = Tracer() - - @tracer.capture_method - def collect_payment_gen(): - yield result - ... + --8<-- "examples/tracer/src/capture_method_generators.py" ``` ## Advanced diff --git a/examples/tracer/src/capture_method_async.py b/examples/tracer/src/capture_method_async.py new file mode 100644 index 00000000000..e142ef8f163 --- /dev/null +++ b/examples/tracer/src/capture_method_async.py @@ -0,0 +1,19 @@ +import asyncio + +from aws_lambda_powertools import Tracer +from aws_lambda_powertools.utilities.typing import LambdaContext + +tracer = Tracer() + + +@tracer.capture_method +async def collect_payment(charge_id: str) -> str: + tracer.put_annotation(key="PaymentId", value=charge_id) + await asyncio.sleep(0.5) + return f"dummy payment collected for charge: {charge_id}" + + +@tracer.capture_lambda_handler +def handler(event: dict, context: LambdaContext) -> str: + charge_id = event.get("charge_id", "") + return asyncio.run(collect_payment(charge_id=charge_id)) diff --git a/examples/tracer/src/capture_method_context_manager.py b/examples/tracer/src/capture_method_context_manager.py new file mode 100644 index 00000000000..083443607ac --- /dev/null +++ b/examples/tracer/src/capture_method_context_manager.py @@ -0,0 +1,27 @@ +import contextlib +from collections.abc import Generator + +from aws_lambda_powertools import Logger, Tracer +from aws_lambda_powertools.utilities.typing import LambdaContext + +tracer = Tracer() +logger = Logger() + + +@contextlib.contextmanager +@tracer.capture_method +def collect_payment(charge_id: str) -> Generator[str, None, None]: + try: + yield f"dummy payment collected for charge: {charge_id}" + finally: + tracer.put_annotation(key="PaymentId", value=charge_id) + + +@tracer.capture_lambda_handler +@logger.inject_lambda_context +def handler(event: dict, context: LambdaContext) -> str: + charge_id = event.get("charge_id", "") + with collect_payment(charge_id=charge_id) as receipt_id: + logger.info(f"Processing payment collection for charge {charge_id} with receipt {receipt_id}") + + return receipt_id diff --git a/examples/tracer/src/capture_method_generators.py b/examples/tracer/src/capture_method_generators.py new file mode 100644 index 00000000000..65b87c251e8 --- /dev/null +++ b/examples/tracer/src/capture_method_generators.py @@ -0,0 +1,17 @@ +from collections.abc import Generator + +from aws_lambda_powertools import Tracer +from aws_lambda_powertools.utilities.typing import LambdaContext + +tracer = Tracer() + + +@tracer.capture_method +def collect_payment(charge_id: str) -> Generator[str, None, None]: + yield f"dummy payment collected for charge: {charge_id}" + + +@tracer.capture_lambda_handler +def handler(event: dict, context: LambdaContext) -> str: + charge_id = event.get("charge_id", "") + return next(collect_payment(charge_id=charge_id)) From e5d89a754b1aa7df8f5c7e30edbc3cc00ce27250 Mon Sep 17 00:00:00 2001 From: heitorlessa Date: Thu, 23 Jun 2022 17:01:15 +0200 Subject: [PATCH 17/25] docs(tracer): split patch_modules --- docs/core/tracer.md | 10 ++-------- examples/tracer/src/patch_modules.py | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 8 deletions(-) create mode 100644 examples/tracer/src/patch_modules.py diff --git a/docs/core/tracer.md b/docs/core/tracer.md index d9875d3d24d..a1b100fd20b 100644 --- a/docs/core/tracer.md +++ b/docs/core/tracer.md @@ -100,14 +100,8 @@ Tracer automatically patches all [supported libraries by X-Ray](https://docs.aws If you're looking to shave a few microseconds, or milliseconds depending on your function memory configuration, you can patch specific modules using `patch_modules` param: -```python hl_lines="7" title="Example of explicitly patching boto3 and requests only" -import boto3 -import requests - -from aws_lambda_powertools import Tracer - -modules_to_be_patched = ["boto3", "requests"] -tracer = Tracer(patch_modules=modules_to_be_patched) +```python hl_lines="8" title="Example of explicitly patching requests only" +--8<-- "examples/tracer/src/patch_modules.py" ``` ### Disabling response auto-capture diff --git a/examples/tracer/src/patch_modules.py b/examples/tracer/src/patch_modules.py new file mode 100644 index 00000000000..09e7092a85a --- /dev/null +++ b/examples/tracer/src/patch_modules.py @@ -0,0 +1,16 @@ +import requests + +from aws_lambda_powertools import Tracer +from aws_lambda_powertools.utilities.typing import LambdaContext + +MODULES = ["requests"] + +tracer = Tracer(patch_modules=MODULES) + + +@tracer.capture_lambda_handler +def handler(event: dict, context: LambdaContext) -> str: + ret = requests.get("https://httpbin.org/get") + ret.raise_for_status() + + return ret.json() From fd5df4b9686f5c49e3761308e2f2524db771fc06 Mon Sep 17 00:00:00 2001 From: heitorlessa Date: Thu, 23 Jun 2022 17:13:05 +0200 Subject: [PATCH 18/25] docs(tracer): split disable capture response --- docs/core/tracer.md | 23 ++++---------- .../tracer/src/disable_capture_response.py | 18 +++++++++++ ...disable_capture_response_streaming_body.py | 30 +++++++++++++++++++ 3 files changed, 53 insertions(+), 18 deletions(-) create mode 100644 examples/tracer/src/disable_capture_response.py create mode 100644 examples/tracer/src/disable_capture_response_streaming_body.py diff --git a/docs/core/tracer.md b/docs/core/tracer.md index a1b100fd20b..f88277c5552 100644 --- a/docs/core/tracer.md +++ b/docs/core/tracer.md @@ -115,27 +115,14 @@ Use **`capture_response=False`** parameter in both `capture_lambda_handler` and === "sensitive_data_scenario.py" - ```python hl_lines="3 7" - from aws_lambda_powertools import Tracer - - @tracer.capture_method(capture_response=False) - def fetch_sensitive_information(): - return "sensitive_information" - - @tracer.capture_lambda_handler(capture_response=False) - def handler(event, context): - sensitive_information = fetch_sensitive_information() + ```python hl_lines="8 15" + --8<-- "examples/tracer/src/disable_capture_response.py" ``` -=== "streaming_object_scenario.py" - ```python hl_lines="3" - from aws_lambda_powertools import Tracer +=== "streaming_object_scenario.py" - @tracer.capture_method(capture_response=False) - def get_s3_object(bucket_name, object_key): - s3 = boto3.client("s3") - s3_object = get_object(Bucket=bucket_name, Key=object_key) - return s3_object + ```python hl_lines="18" + --8<-- "examples/tracer/src/disable_capture_response_streaming_body.py" ``` ### Disabling exception auto-capture diff --git a/examples/tracer/src/disable_capture_response.py b/examples/tracer/src/disable_capture_response.py new file mode 100644 index 00000000000..ffe8230eece --- /dev/null +++ b/examples/tracer/src/disable_capture_response.py @@ -0,0 +1,18 @@ +from aws_lambda_powertools import Logger, Tracer +from aws_lambda_powertools.utilities.typing import LambdaContext + +tracer = Tracer() +logger = Logger() + + +@tracer.capture_method(capture_response=False) +def collect_payment(charge_id: str) -> str: + tracer.put_annotation(key="PaymentId", value=charge_id) + logger.debug("Returning sensitive information....") + return f"dummy payment collected for charge: {charge_id}" + + +@tracer.capture_lambda_handler(capture_response=False) +def handler(event: dict, context: LambdaContext) -> str: + charge_id = event.get("charge_id", "") + return collect_payment(charge_id=charge_id) diff --git a/examples/tracer/src/disable_capture_response_streaming_body.py b/examples/tracer/src/disable_capture_response_streaming_body.py new file mode 100644 index 00000000000..3e458a98eb4 --- /dev/null +++ b/examples/tracer/src/disable_capture_response_streaming_body.py @@ -0,0 +1,30 @@ +import os + +import boto3 +from botocore.response import StreamingBody + +from aws_lambda_powertools import Logger, Tracer +from aws_lambda_powertools.utilities.typing import LambdaContext + +BUCKET = os.getenv("BUCKET_NAME", "") +REPORT_KEY = os.getenv("REPORT_KEY", "") + +tracer = Tracer() +logger = Logger() + +session = boto3.Session() +s3 = session.client("s3") + + +@tracer.capture_method(capture_response=False) +def fetch_payment_report(payment_id: str) -> StreamingBody: + ret = s3.get_object(Bucket=BUCKET, Key=f"{REPORT_KEY}/{payment_id}") + logger.debug("Returning streaming body from S3 object....") + return ret["body"] + + +@tracer.capture_lambda_handler(capture_response=False) +def handler(event: dict, context: LambdaContext) -> str: + payment_id = event.get("payment_id", "") + report = fetch_payment_report(payment_id=payment_id) + return report.read().decode() From c556f57ab1e77ab2caa1bd32866f8a8af34ada89 Mon Sep 17 00:00:00 2001 From: heitorlessa Date: Thu, 23 Jun 2022 17:13:50 +0200 Subject: [PATCH 19/25] docs(tracer): fix highlighting after linting --- docs/core/tracer.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/core/tracer.md b/docs/core/tracer.md index f88277c5552..1d8e49e028c 100644 --- a/docs/core/tracer.md +++ b/docs/core/tracer.md @@ -121,7 +121,7 @@ Use **`capture_response=False`** parameter in both `capture_lambda_handler` and === "streaming_object_scenario.py" - ```python hl_lines="18" + ```python hl_lines="19" --8<-- "examples/tracer/src/disable_capture_response_streaming_body.py" ``` From b2497fdf073e6f8af113aa7694fd0c0440e821e7 Mon Sep 17 00:00:00 2001 From: heitorlessa Date: Thu, 23 Jun 2022 17:22:43 +0200 Subject: [PATCH 20/25] docs(tracer): snippet capture error --- docs/core/tracer.md | 8 ++--- examples/tracer/src/disable_capture_error.py | 31 ++++++++++++++++++++ 2 files changed, 33 insertions(+), 6 deletions(-) create mode 100644 examples/tracer/src/disable_capture_error.py diff --git a/docs/core/tracer.md b/docs/core/tracer.md index 1d8e49e028c..cdaa1fa063e 100644 --- a/docs/core/tracer.md +++ b/docs/core/tracer.md @@ -132,12 +132,8 @@ Use **`capture_error=False`** parameter in both `capture_lambda_handler` and `ca ???+ info Useful when returning sensitive information in exceptions/stack traces you don't control -```python hl_lines="3 5" title="Disabling exception auto-capture for tracing metadata" -from aws_lambda_powertools import Tracer - -@tracer.capture_lambda_handler(capture_error=False) -def handler(event, context): - raise ValueError("some sensitive info in the stack trace...") +```python hl_lines="16 26" title="Disabling exception auto-capture for tracing metadata" +--8<-- "examples/tracer/src/disable_capture_error.py" ``` ### Ignoring certain HTTP endpoints diff --git a/examples/tracer/src/disable_capture_error.py b/examples/tracer/src/disable_capture_error.py new file mode 100644 index 00000000000..7b7d7e6ad23 --- /dev/null +++ b/examples/tracer/src/disable_capture_error.py @@ -0,0 +1,31 @@ +import os + +import requests + +from aws_lambda_powertools import Tracer +from aws_lambda_powertools.utilities.typing import LambdaContext + +tracer = Tracer() +ENDPOINT = os.getenv("PAYMENT_API", "") + + +class PaymentError(Exception): + ... + + +@tracer.capture_method(capture_error=False) +def collect_payment(charge_id: str) -> dict: + try: + ret = requests.post(url=f"{ENDPOINT}/collect", data={"charge_id": charge_id}) + ret.raise_for_status() + return ret.json() + except requests.HTTPError as e: + raise PaymentError(f"Unable to collect payment for charge {charge_id}") from e + + +@tracer.capture_lambda_handler(capture_error=False) +def handler(event: dict, context: LambdaContext) -> str: + charge_id = event.get("charge_id", "") + ret = collect_payment(charge_id=charge_id) + + return ret.get("receipt_id", "") From 6a4654eace2ac09e163ec88d47db60bda03cb8be Mon Sep 17 00:00:00 2001 From: heitorlessa Date: Thu, 23 Jun 2022 17:49:22 +0200 Subject: [PATCH 21/25] docs(tracer): snippet ignore endpoints --- docs/core/tracer.md | 19 ++------------ examples/tracer/src/ignore_endpoints.py | 35 +++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 17 deletions(-) create mode 100644 examples/tracer/src/ignore_endpoints.py diff --git a/docs/core/tracer.md b/docs/core/tracer.md index cdaa1fa063e..f97b6d15e4a 100644 --- a/docs/core/tracer.md +++ b/docs/core/tracer.md @@ -142,23 +142,8 @@ You might have endpoints you don't want requests to be traced, perhaps due to th You can use `ignore_endpoint` method with the hostname and/or URLs you'd like it to be ignored - globs (`*`) are allowed. -```python title="Ignoring certain HTTP endpoints from being traced" -from aws_lambda_powertools import Tracer - -tracer = Tracer() -# ignore all calls to `ec2.amazon.com` -tracer.ignore_endpoint(hostname="ec2.amazon.com") -# ignore calls to `*.sensitive.com/password` and `*.sensitive.com/credit-card` -tracer.ignore_endpoint(hostname="*.sensitive.com", urls=["/password", "/credit-card"]) - - -def ec2_api_calls(): - return "suppress_api_responses" - -@tracer.capture_lambda_handler -def handler(event, context): - for x in long_list: - ec2_api_calls() +```python hl_lines="12-13" title="Ignoring certain HTTP endpoints from being traced" +--8<-- "examples/tracer/src/ignore_endpoints.py" ``` ### Tracing aiohttp requests diff --git a/examples/tracer/src/ignore_endpoints.py b/examples/tracer/src/ignore_endpoints.py new file mode 100644 index 00000000000..6484cfcf5b0 --- /dev/null +++ b/examples/tracer/src/ignore_endpoints.py @@ -0,0 +1,35 @@ +import os + +import requests + +from aws_lambda_powertools import Tracer +from aws_lambda_powertools.utilities.typing import LambdaContext + +ENDPOINT = os.getenv("PAYMENT_API", "") +IGNORE_URLS = ["/collect", "/refund"] + +tracer = Tracer() +tracer.ignore_endpoint(hostname=ENDPOINT, urls=IGNORE_URLS) +tracer.ignore_endpoint(hostname=f"*.{ENDPOINT}", urls=IGNORE_URLS) # `.ENDPOINT` + + +class PaymentError(Exception): + ... + + +@tracer.capture_method(capture_error=False) +def collect_payment(charge_id: str) -> dict: + try: + ret = requests.post(url=f"{ENDPOINT}/collect", data={"charge_id": charge_id}) + ret.raise_for_status() + return ret.json() + except requests.HTTPError as e: + raise PaymentError(f"Unable to collect payment for charge {charge_id}") from e + + +@tracer.capture_lambda_handler(capture_error=False) +def handler(event: dict, context: LambdaContext) -> str: + charge_id = event.get("charge_id", "") + ret = collect_payment(charge_id=charge_id) + + return ret.get("receipt_id", "") From b82dd713661156e605a30eea99b5f04edfb0a874 Mon Sep 17 00:00:00 2001 From: heitorlessa Date: Thu, 23 Jun 2022 18:16:44 +0200 Subject: [PATCH 22/25] docs(tracer): snippet aiohttp --- docs/core/tracer.md | 18 +++--------------- examples/tracer/src/tracing_aiohttp.py | 25 +++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 15 deletions(-) create mode 100644 examples/tracer/src/tracing_aiohttp.py diff --git a/docs/core/tracer.md b/docs/core/tracer.md index f97b6d15e4a..b8d6b9353f3 100644 --- a/docs/core/tracer.md +++ b/docs/core/tracer.md @@ -151,22 +151,10 @@ You can use `ignore_endpoint` method with the hostname and/or URLs you'd like it ???+ info This snippet assumes you have aiohttp as a dependency -You can use `aiohttp_trace_config` function to create a valid [aiohttp trace_config object](https://docs.aiohttp.org/en/stable/tracing_reference.html). This is necessary since X-Ray utilizes aiohttp trace hooks to capture requests end-to-end. +You can use `aiohttp_trace_config` function to create a valid [aiohttp trace_config object](https://docs.aiohttp.org/en/stable/tracing_reference.html){target="_blank"}. This is necessary since X-Ray utilizes [aiohttp](https://docs.aiohttp.org/en/stable/){target="_blank"} trace hooks to capture requests end-to-end. -```python hl_lines="5 10" title="Tracing aiohttp requests" -import asyncio -import aiohttp - -from aws_lambda_powertools import Tracer -from aws_lambda_powertools.tracing import aiohttp_trace_config - -tracer = Tracer() - -async def aiohttp_task(): - async with aiohttp.ClientSession(trace_configs=[aiohttp_trace_config()]) as session: - async with session.get("https://httpbin.org/json") as resp: - resp = await resp.json() - return resp +```python hl_lines="7 17" title="Tracing aiohttp requests" +--8<-- "examples/tracer/src/tracing_aiohttp.py" ``` ### Escape hatch mechanism diff --git a/examples/tracer/src/tracing_aiohttp.py b/examples/tracer/src/tracing_aiohttp.py new file mode 100644 index 00000000000..45fe6a46f38 --- /dev/null +++ b/examples/tracer/src/tracing_aiohttp.py @@ -0,0 +1,25 @@ +import asyncio +import os + +import aiohttp + +from aws_lambda_powertools import Tracer +from aws_lambda_powertools.tracing import aiohttp_trace_config +from aws_lambda_powertools.utilities.typing import LambdaContext + +ENDPOINT = os.getenv("PAYMENT_API", "") + +tracer = Tracer() + + +@tracer.capture_method +async def collect_payment(charge_id: str) -> dict: + async with aiohttp.ClientSession(trace_configs=[aiohttp_trace_config()]) as session: + async with session.get(f"{ENDPOINT}/collect") as resp: + return await resp.json() + + +@tracer.capture_lambda_handler +def handler(event: dict, context: LambdaContext) -> dict: + charge_id = event.get("charge_id", "") + return asyncio.run(collect_payment(charge_id=charge_id)) From a9423471beabaa5bcc961e939e2ccb0aef4ac722 Mon Sep 17 00:00:00 2001 From: heitorlessa Date: Thu, 23 Jun 2022 18:31:39 +0200 Subject: [PATCH 23/25] docs(tracer): snippet escape hatch --- docs/core/tracer.md | 12 ++---------- examples/tracer/src/sdk_escape_hatch.py | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 10 deletions(-) create mode 100644 examples/tracer/src/sdk_escape_hatch.py diff --git a/docs/core/tracer.md b/docs/core/tracer.md index b8d6b9353f3..0a7b054ca5b 100644 --- a/docs/core/tracer.md +++ b/docs/core/tracer.md @@ -163,16 +163,8 @@ You can use `tracer.provider` attribute to access all methods provided by AWS X- This is useful when you need a feature available in X-Ray that is not available in the Tracer utility, for example [thread-safe](https://github.com/aws/aws-xray-sdk-python/#user-content-trace-threadpoolexecutor), or [context managers](https://github.com/aws/aws-xray-sdk-python/#user-content-start-a-custom-segmentsubsegment). -```python hl_lines="7" title="Tracing a code block with in_subsegment escape hatch" -from aws_lambda_powertools import Tracer - -tracer = Tracer() - -@tracer.capture_lambda_handler -def handler(event, context): - with tracer.provider.in_subsegment('## custom subsegment') as subsegment: - ret = some_work() - subsegment.put_metadata('response', ret) +```python hl_lines="14" title="Tracing a code block with in_subsegment escape hatch" +--8<-- "examples/tracer/src/sdk_escape_hatch.py" ``` ### Concurrent asynchronous functions diff --git a/examples/tracer/src/sdk_escape_hatch.py b/examples/tracer/src/sdk_escape_hatch.py new file mode 100644 index 00000000000..7f046caff9d --- /dev/null +++ b/examples/tracer/src/sdk_escape_hatch.py @@ -0,0 +1,19 @@ +from aws_lambda_powertools import Tracer +from aws_lambda_powertools.utilities.typing import LambdaContext + +tracer = Tracer() + + +def collect_payment(charge_id: str) -> str: + return f"dummy payment collected for charge: {charge_id}" + + +@tracer.capture_lambda_handler +def handler(event: dict, context: LambdaContext) -> str: + charge_id = event.get("charge_id", "") + with tracer.provider.in_subsegment("## collect_payment") as subsegment: + subsegment.put_annotation(key="PaymentId", value=charge_id) + ret = collect_payment(charge_id=charge_id) + subsegment.put_metadata(key="payment_response", value=ret) + + return ret From 139af49a92204b3686ac39d0e0c8f6ea7d4cfa3a Mon Sep 17 00:00:00 2001 From: heitorlessa Date: Thu, 23 Jun 2022 20:49:20 +0200 Subject: [PATCH 24/25] docs(tracer): snippet async concurrency --- docs/core/tracer.md | 22 ++----------- .../src/capture_method_async_concurrency.py | 31 +++++++++++++++++++ 2 files changed, 34 insertions(+), 19 deletions(-) create mode 100644 examples/tracer/src/capture_method_async_concurrency.py diff --git a/docs/core/tracer.md b/docs/core/tracer.md index 0a7b054ca5b..75083fb55c3 100644 --- a/docs/core/tracer.md +++ b/docs/core/tracer.md @@ -174,25 +174,8 @@ This is useful when you need a feature available in X-Ray that is not available A safe workaround mechanism is to use `in_subsegment_async` available via Tracer escape hatch (`tracer.provider`). -```python hl_lines="6 7 12 15 17" title="Workaround to safely trace async concurrent functions" -import asyncio - -from aws_lambda_powertools import Tracer -tracer = Tracer() - -async def another_async_task(): - async with tracer.provider.in_subsegment_async("## another_async_task") as subsegment: - subsegment.put_annotation(key="key", value="value") - subsegment.put_metadata(key="key", value="value", namespace="namespace") - ... - -async def another_async_task_2(): - ... - -@tracer.capture_method -async def collect_payment(charge_id): - asyncio.gather(another_async_task(), another_async_task_2()) - ... +```python hl_lines="10 17 24" title="Workaround to safely trace async concurrent functions" +--8<-- "examples/tracer/src/capture_method_async_concurrency.py" ``` ### Reusing Tracer across your code @@ -219,6 +202,7 @@ Tracer keeps a copy of its configuration after the first initialization. This is charge_id = event.get('charge_id') payment = collect_payment(charge_id) ``` + === "payment.py" A new instance of Tracer will be created but will reuse the previous Tracer instance configuration, similar to a Singleton. diff --git a/examples/tracer/src/capture_method_async_concurrency.py b/examples/tracer/src/capture_method_async_concurrency.py new file mode 100644 index 00000000000..82e89070c75 --- /dev/null +++ b/examples/tracer/src/capture_method_async_concurrency.py @@ -0,0 +1,31 @@ +import asyncio + +from aws_lambda_powertools import Tracer +from aws_lambda_powertools.utilities.typing import LambdaContext + +tracer = Tracer() + + +async def another_async_task(): + async with tracer.provider.in_subsegment_async("## another_async_task") as subsegment: + subsegment.put_annotation(key="key", value="value") + subsegment.put_metadata(key="key", value="value", namespace="namespace") + ... + + +async def another_async_task_2(): + async with tracer.provider.in_subsegment_async("## another_async_task_2") as subsegment: + subsegment.put_annotation(key="key", value="value") + subsegment.put_metadata(key="key", value="value", namespace="namespace") + ... + + +async def collect_payment(charge_id: str) -> str: + await asyncio.gather(another_async_task(), another_async_task_2()) + return f"dummy payment collected for charge: {charge_id}" + + +@tracer.capture_lambda_handler +def handler(event: dict, context: LambdaContext) -> str: + charge_id = event.get("charge_id", "") + return asyncio.run(collect_payment(charge_id=charge_id)) From bc4a1a333ee8fc95169fce4951b7ce2f1ca3647c Mon Sep 17 00:00:00 2001 From: heitorlessa Date: Thu, 23 Jun 2022 20:58:26 +0200 Subject: [PATCH 25/25] docs(tracer): snippet tracer reuse --- docs/core/tracer.md | 24 +++++---------------- examples/tracer/src/tracer_reuse.py | 12 +++++++++++ examples/tracer/src/tracer_reuse_payment.py | 8 +++++++ 3 files changed, 25 insertions(+), 19 deletions(-) create mode 100644 examples/tracer/src/tracer_reuse.py create mode 100644 examples/tracer/src/tracer_reuse_payment.py diff --git a/docs/core/tracer.md b/docs/core/tracer.md index 75083fb55c3..34eb1ed2b93 100644 --- a/docs/core/tracer.md +++ b/docs/core/tracer.md @@ -191,29 +191,15 @@ Tracer keeps a copy of its configuration after the first initialization. This is === "handler.py" - ```python hl_lines="2 4 9" - from aws_lambda_powertools import Tracer - from payment import collect_payment - - tracer = Tracer(service="payment") - - @tracer.capture_lambda_handler - def handler(event, context): - charge_id = event.get('charge_id') - payment = collect_payment(charge_id) + ```python hl_lines="1 6" + --8<-- "examples/tracer/src/tracer_reuse.py" ``` -=== "payment.py" +=== "tracer_reuse_payment.py" A new instance of Tracer will be created but will reuse the previous Tracer instance configuration, similar to a Singleton. - ```python hl_lines="3 5" - from aws_lambda_powertools import Tracer - - tracer = Tracer(service="payment") - - @tracer.capture_method - def collect_payment(charge_id: str): - ... + ```python hl_lines="3" + --8<-- "examples/tracer/src/tracer_reuse_payment.py" ``` ## Testing your code diff --git a/examples/tracer/src/tracer_reuse.py b/examples/tracer/src/tracer_reuse.py new file mode 100644 index 00000000000..5f12f82b714 --- /dev/null +++ b/examples/tracer/src/tracer_reuse.py @@ -0,0 +1,12 @@ +from tracer_reuse_payment import collect_payment + +from aws_lambda_powertools import Tracer +from aws_lambda_powertools.utilities.typing import LambdaContext + +tracer = Tracer() + + +@tracer.capture_lambda_handler +def handler(event: dict, context: LambdaContext) -> str: + charge_id = event.get("charge_id", "") + return collect_payment(charge_id=charge_id) diff --git a/examples/tracer/src/tracer_reuse_payment.py b/examples/tracer/src/tracer_reuse_payment.py new file mode 100644 index 00000000000..109d1cfbc53 --- /dev/null +++ b/examples/tracer/src/tracer_reuse_payment.py @@ -0,0 +1,8 @@ +from aws_lambda_powertools import Tracer + +tracer = Tracer() + + +@tracer.capture_method +def collect_payment(charge_id: str) -> str: + return f"dummy payment collected for charge: {charge_id}"