title | description |
---|---|
Tracer |
Core utility |
import Note from "../../src/components/Note"
Tracer is an opinionated thin wrapper for AWS X-Ray Python SDK.
Key features
- Capture cold start as annotation, and responses as well as full exceptions as metadata
- Run functions locally with SAM CLI without code change to disable tracing
- Explicitly disable tracing via env var
POWERTOOLS_TRACE_DISABLED="true"
- Support tracing async methods
- Auto patch supported modules, or a tuple of explicit modules supported by AWS X-Ray
Your AWS Lambda function must have permission to send traces to AWS X-Ray - Here is an example using AWS Serverless Application Model (SAM)
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function
Properties:
...
Runtime: python3.8
Tracing: Active # highlight-line
Environment:
Variables:
POWERTOOLS_SERVICE_NAME: example
You can either explicitly pass using service
param or via POWERTOOLS_SERVICE_NAME
environment variable. The service name is utilized for exceptions, metadata, and namespace data.
from aws_lambda_powertools.tracing import Tracer
# POWERTOOLS_SERVICE_NAME defined
tracer = Tracer() # highlight-line
# Explicit definition
tracer = Tracer(service="booking")
You can trace your Lambda function handler via capture_lambda_handler
.
When using this decorator, Tracer performs these additional tasks to ease operations:
- Creates a
ColdStart
annotation to easily filter traces that have had an initialization overhead - Adds any response, or full exceptions generated by the handler as metadata
from aws_lambda_powertools.tracing import Tracer
tracer = Tracer()
@tracer.capture_lambda_handler # highlight-line
def handler(event, context)
charge_id = event.get('charge_id')
payment = collect_payment(charge_id)
...
Annotations are key-values indexed by AWS X-Ray on a per trace basis. You can use them to filter traces as well as to create Trace Groups.
You can add annotations using put_annotation
method from Tracer.
from aws_lambda_powertools.tracing import Tracer
tracer = Tracer()
@tracer.capture_lambda_handler
def handler(event, context):
...
tracer.put_annotation(key="PaymentStatus", value="SUCCESS") # highlight-line
Metadata are non-indexed values that can add additional context for an operation.
You can add metadata using put_metadata
method from Tracer.
from aws_lambda_powertools.tracing import Tracer
tracer = Tracer()
@tracer.capture_lambda_handler
def handler(event, context):
...
ret = some_logic()
tracer.put_metadata(key="payment_response", value=ret) # highlight-line
You can trace a synchronous function using the 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
...
You can trace an asynchronous function using the capture_method
. The decorator will detect whether your function is asynchronous, and adapt its behaviour accordingly.
import asyncio
from aws_lambda_powertools.tracing import Tracer
tracer = Tracer()
# highlight-start
@tracer.capture_method
async def collect_payment():
...
# highlight-end
@tracer.capture_lambda_handler
def handler(evt, ctx): # highlight-line
asyncio.run(collect_payment())
You can use aiohttp_trace_config
function to create a valid aiohttp trace_config object. This is necessary since X-Ray utilizes aiohttp trace hooks to capture requests end-to-end.
import asyncio
import aiohttp
from aws_lambda_powertools.tracing import Tracer, aiohttp_trace_config # highlight-line
tracer = Tracer()
async def aiohttp_task():
async with aiohttp.ClientSession(trace_configs=[aiohttp_trace_config()]) as session: # highlight-line
async with session.get("https://httpbin.org/json") as resp:
resp = await resp.json()
return resp
You can use tracer.provider
attribute to access all methods provided by AWS X-Ray xray_recorder
object.
This is useful when you need a feature available in X-Ray that is not available in the Tracer utility, for example thread-safe, or context managers.
As of now, X-Ray SDK will raise an exception when async functions are run and traced concurrently.A safe workaround mechanism is to use in_subsegment_async
available via Tracer escape hatch (tracer.provider
).
import asyncio
from aws_lambda_powertools.tracing import Tracer
tracer = Tracer()
async def another_async_task():
# highlight-start
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")
...
# highlight-end
async def another_async_task_2():
...
@tracer.capture_method
async def collect_payment(charge_id):
asyncio.gather(another_async_task(), another_async_task_2()) # highlight-line
...
Tracer keeps a copy of its configuration after the first initialization. This is useful for scenarios where you want to use Tracer in more than one location across your code base.
# handler.py
from aws_lambda_powertools.tracing import Tracer
tracer = Tracer(service="payment")
@tracer.capture_lambda_handler
def handler(event, context)
charge_id = event.get('charge_id')
payment = collect_payment(charge_id)
...
from aws_lambda_powertools.tracing import Tracer
# highlight-start
# new instance using existing configuration with auto patching overriden
tracer = Tracer(auto_patch=False)
# highlight-end
You can safely disable Tracer when unit testing your code using POWERTOOLS_TRACE_DISABLED
environment variable.
POWERTOOLS_TRACE_DISABLED=1 python -m pytest
- Use annotations on key operations to slice and dice traces, create unique views, and create metrics from it via Trace Groups
- Use a namespace when adding metadata to group data more easily
- Annotations and metadata are added to the current subsegment opened. If you want them in a specific subsegment, use a context manager via the escape hatch mechanism