Skip to content

Latest commit

 

History

History
213 lines (135 loc) · 8.92 KB

File metadata and controls

213 lines (135 loc) · 8.92 KB
title description
Tracer
Core utility

Tracer is an opinionated thin wrapper for AWS X-Ray Python SDK.

Tracer showcase

Key features

  • Auto capture cold start as annotation, and responses or full exceptions as metadata
  • Auto-disable when not running in AWS Lambda environment
  • Support tracing async methods, generators, and context managers
  • Auto patch supported modules by AWS X-Ray

Getting started

Permissions

Before your use this utility, your AWS Lambda function must have permissions to send traces to AWS X-Ray.

--8<-- "examples/tracer/template.yaml"

Lambda handler

You can quickly start by initializing Tracer and use capture_lambda_handler decorator for your Lambda handler.

--8<-- "examples/tracer/src/capture_lambda_handler.py"

capture_lambda_handler performs these additional tasks to ease operations:

  • Creates a ColdStart annotation to easily filter traces that have had an initialization overhead
  • Creates a Service annotation if service parameter or POWERTOOLS_SERVICE_NAME is set
  • Captures any response, or full exceptions generated by the handler, and include as tracing metadata

Annotations & Metadata

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 to slice and dice your transactions.

--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.

--8<-- "examples/tracer/src/put_trace_metadata.py"

Synchronous functions

You can trace synchronous functions using the capture_method decorator.

--8<-- "examples/tracer/src/capture_method.py"

???+ note "Note: Function responses are auto-captured and stored as JSON, by default."

Use [capture_response](#disabling-response-auto-capture) parameter to override this behaviour.

The serialization is performed by aws-xray-sdk via `jsonpickle` module. This can cause
side effects for file-like objects like boto S3 <a href="https://botocore.amazonaws.com/v1/documentation/api/latest/reference/response.html#botocore.response.StreamingBody">`StreamingBody`</a>, where its response will be read only once during serialization.

Asynchronous and generator functions

???+ warning We do not support asynchronous Lambda handler

You can trace asynchronous functions and generator functions (including context managers) using capture_method.

=== "Async"

```python hl_lines="8"
--8<-- "examples/tracer/src/capture_method_async.py"
```

=== "Context manager"

```python hl_lines="12-13"
--8<-- "examples/tracer/src/capture_method_context_manager.py"
```

=== "Generators"

```python hl_lines="9"
--8<-- "examples/tracer/src/capture_method_generators.py"
```

Advanced

Patching modules

Tracer automatically patches all supported libraries by X-Ray during initialization, by default. Underneath, AWS X-Ray SDK checks whether a supported library has been imported before patching.

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:

--8<-- "examples/tracer/src/patch_modules.py"

Disabling response auto-capture

Use capture_response=False parameter in both capture_lambda_handler and capture_method decorators to instruct Tracer not to serialize function responses as metadata.

???+ info "Info: This is useful in three common scenarios" 1. You might return sensitive information you don't want it to be added to your traces 2. You might manipulate streaming objects that can be read only once; this prevents subsequent calls from being empty 3. You might return more than 64K of data e.g., message too long error

=== "sensitive_data_scenario.py"

```python hl_lines="8 15"
--8<-- "examples/tracer/src/disable_capture_response.py"
```

=== "streaming_object_scenario.py"

```python hl_lines="19"
--8<-- "examples/tracer/src/disable_capture_response_streaming_body.py"
```

Disabling exception auto-capture

Use capture_error=False parameter in both capture_lambda_handler and capture_method decorators to instruct Tracer not to serialize exceptions as metadata.

???+ info Useful when returning sensitive information in exceptions/stack traces you don't control

--8<-- "examples/tracer/src/disable_capture_error.py"

Ignoring certain HTTP endpoints

You might have endpoints you don't want requests to be traced, perhaps due to the volume of calls or sensitive URLs.

You can use ignore_endpoint method with the hostname and/or URLs you'd like it to be ignored - globs (*) are allowed.

--8<-- "examples/tracer/src/ignore_endpoints.py"

Tracing aiohttp requests

???+ 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{target="_blank"}. This is necessary since X-Ray utilizes aiohttp{target="_blank"} trace hooks to capture requests end-to-end.

--8<-- "examples/tracer/src/tracing_aiohttp.py"

Escape hatch mechanism

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.

--8<-- "examples/tracer/src/sdk_escape_hatch.py"

Concurrent asynchronous functions

???+ warning 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).

--8<-- "examples/tracer/src/capture_method_async_concurrency.py"

Reusing Tracer across your code

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.

???+ warning "Warning: Import order matters when using Lambda Layers or multiple modules" Do not set auto_patch=False when reusing Tracer in Lambda Layers, or in multiple modules.

This can result in the first Tracer config being inherited by new instances, and their modules not being patched.

Tracer will automatically ignore imported modules that have been patched.

=== "handler.py"

```python hl_lines="1 6"
--8<-- "examples/tracer/src/tracer_reuse.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"
--8<-- "examples/tracer/src/tracer_reuse_payment.py"
```

Testing your code

Tracer is disabled by default when not running in the AWS Lambda environment - This means no code changes or environment variables to be set.

Tips

  • 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