|
1 | 1 | # Lambda Powertools
|
2 | 2 |
|
3 |
| -  |
| 3 | +     |
4 | 4 |
|
5 | 5 | A suite of utilities for AWS Lambda Functions that makes tracing with AWS X-Ray, structured logging and creating custom metrics asynchronously easier - Currently available for Python only and compatible with Python >=3.6.
|
6 | 6 |
|
@@ -32,12 +32,20 @@ A suite of utilities for AWS Lambda Functions that makes tracing with AWS X-Ray,
|
32 | 32 | * Validate against common metric definitions mistakes (metric unit, values, max dimensions, max metrics, etc)
|
33 | 33 | * No stack, custom resource, data collection needed — Metrics are created async by CloudWatch EMF
|
34 | 34 |
|
| 35 | +**Bring your own middleware** |
| 36 | + |
| 37 | +* Utility to easily create your own middleware |
| 38 | +* Run logic before, after, and handle exceptions |
| 39 | +* Receive lambda handler, event, context |
| 40 | +* Optionally create sub-segment for each custom middleware |
| 41 | + |
35 | 42 | **Environment variables** used across suite of utilities
|
36 | 43 |
|
37 | 44 | Environment variable | Description | Default | Utility
|
38 | 45 | ------------------------------------------------- | --------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- | -------------------------------------------------
|
39 | 46 | POWERTOOLS_SERVICE_NAME | Sets service name used for tracing namespace, metrics dimensions and structured logging | "service_undefined" | all
|
40 | 47 | POWERTOOLS_TRACE_DISABLED | Disables tracing | "false" | tracing
|
| 48 | +POWERTOOLS_TRACE_MIDDLEWARES | Creates sub-segment for each middleware created by lambda_handler_decorator | "false" | middleware_factory |
41 | 49 | POWERTOOLS_LOGGER_LOG_EVENT | Logs incoming event | "false" | logging
|
42 | 50 | POWERTOOLS_LOGGER_SAMPLE_RATE | Debug log sampling | 0 | logging
|
43 | 51 | POWERTOOLS_METRICS_NAMESPACE | Metrics namespace | None | metrics
|
@@ -85,6 +93,23 @@ def handler(event, context)
|
85 | 93 | ...
|
86 | 94 | ```
|
87 | 95 |
|
| 96 | +**Fetching a pre-configured tracer anywhere** |
| 97 | + |
| 98 | +```python |
| 99 | +# handler.py |
| 100 | +from aws_lambda_powertools.tracing import Tracer |
| 101 | +tracer = Tracer(service="payment") |
| 102 | + |
| 103 | +@tracer.capture_lambda_handler |
| 104 | +def handler(event, context) |
| 105 | + charge_id = event.get('charge_id') |
| 106 | + payment = collect_payment(charge_id) |
| 107 | + ... |
| 108 | + |
| 109 | +# another_file.py |
| 110 | +from aws_lambda_powertools.tracing import Tracer |
| 111 | +tracer = Tracer(auto_patch=False) # new instance using existing configuration with auto patching overriden |
| 112 | +``` |
88 | 113 |
|
89 | 114 | ### Logging
|
90 | 115 |
|
@@ -154,7 +179,7 @@ def handler(event, context)
|
154 | 179 | }
|
155 | 180 | ```
|
156 | 181 |
|
157 |
| -#### Custom Metrics async |
| 182 | +### Custom Metrics async |
158 | 183 |
|
159 | 184 | > **NOTE** `log_metric` will be removed once it's GA.
|
160 | 185 |
|
@@ -204,6 +229,97 @@ with single_metric(name="ColdStart", unit=MetricUnit.Count, value=1) as metric:
|
204 | 229 | metric.add_dimension(name="function_context", value="$LATEST")
|
205 | 230 | ```
|
206 | 231 |
|
| 232 | + |
| 233 | +### Utilities |
| 234 | + |
| 235 | +#### Bring your own middleware |
| 236 | + |
| 237 | +This feature allows you to create your own middleware as a decorator with ease by following a simple signature. |
| 238 | + |
| 239 | +* Accept 3 mandatory args - `handler, event, context` |
| 240 | +* Always return the handler with event/context or response if executed |
| 241 | + - Supports nested middleware/decorators use case |
| 242 | + |
| 243 | +**Middleware with no params** |
| 244 | + |
| 245 | +```python |
| 246 | +from aws_lambda_powertools.middleware_factory import lambda_handler_decorator |
| 247 | + |
| 248 | +@lambda_handler_decorator |
| 249 | +def middleware_name(handler, event, context): |
| 250 | + return handler(event, context) |
| 251 | + |
| 252 | +@lambda_handler_decorator |
| 253 | +def middleware_before_after(handler, event, context): |
| 254 | + logic_before_handler_execution() |
| 255 | + response = handler(event, context) |
| 256 | + logic_after_handler_execution() |
| 257 | + return response |
| 258 | + |
| 259 | + |
| 260 | +# middleware_name will wrap Lambda handler |
| 261 | +# and simply return the handler as we're not pre/post-processing anything |
| 262 | +# then middleware_before_after will wrap middleware_name |
| 263 | +# run some code before/after calling the handler returned by middleware_name |
| 264 | +# This way, lambda_handler is only actually called once (top-down) |
| 265 | +@middleware_before_after # This will run last |
| 266 | +@middleware_name # This will run first |
| 267 | +def lambda_handler(event, context): |
| 268 | + return True |
| 269 | +``` |
| 270 | + |
| 271 | +**Middleware with params** |
| 272 | + |
| 273 | +```python |
| 274 | +@lambda_handler_decorator |
| 275 | +def obfuscate_sensitive_data(handler, event, context, fields=None): |
| 276 | + # Obfuscate email before calling Lambda handler |
| 277 | + if fields: |
| 278 | + for field in fields: |
| 279 | + field = event.get(field, "") |
| 280 | + event[field] = obfuscate_pii(field) |
| 281 | + |
| 282 | + return handler(event, context) |
| 283 | + |
| 284 | +@obfuscate_sensitive_data(fields=["email"]) |
| 285 | +def lambda_handler(event, context): |
| 286 | + return True |
| 287 | +``` |
| 288 | + |
| 289 | +**Optionally trace middleware execution** |
| 290 | + |
| 291 | +This makes use of an existing Tracer instance that you may have initialized anywhere in your code, otherwise it'll initialize one using default options and provider (X-Ray). |
| 292 | + |
| 293 | +```python |
| 294 | +from aws_lambda_powertools.middleware_factory import lambda_handler_decorator |
| 295 | + |
| 296 | +@lambda_handler_decorator(trace_execution=True) |
| 297 | +def middleware_name(handler, event, context): |
| 298 | + return handler(event, context) |
| 299 | + |
| 300 | +@middleware_name |
| 301 | +def lambda_handler(event, context): |
| 302 | + return True |
| 303 | +``` |
| 304 | + |
| 305 | +Optionally, you can enrich the final trace with additional annotations and metadata by retrieving a copy of the Tracer used. |
| 306 | + |
| 307 | +```python |
| 308 | +from aws_lambda_powertools.middleware_factory import lambda_handler_decorator |
| 309 | +from aws_lambda_powertools.tracing import Tracer |
| 310 | + |
| 311 | +@lambda_handler_decorator(trace_execution=True) |
| 312 | +def middleware_name(handler, event, context): |
| 313 | + tracer = Tracer() # Takes a copy of an existing tracer instance |
| 314 | + tracer.add_anotation... |
| 315 | + tracer.metadata... |
| 316 | + return handler(event, context) |
| 317 | + |
| 318 | +@middleware_name |
| 319 | +def lambda_handler(event, context): |
| 320 | + return True |
| 321 | +``` |
| 322 | + |
207 | 323 | ## Beta
|
208 | 324 |
|
209 | 325 | > **[Progress towards GA](https://github.com/awslabs/aws-lambda-powertools/projects/1)**
|
|
0 commit comments