|
2 | 2 |
|
3 | 3 |  
|
4 | 4 |
|
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. |
| 5 | +A suite of utilities for AWS Lambda Functions that makes tracing with AWS X-Ray, structured logging and creating custom metrics asynchronously easier. |
6 | 6 |
|
7 |
| -**Status**: Beta |
| 7 | +## Powertools available |
8 | 8 |
|
9 |
| -## Features |
10 |
| - |
11 |
| -**Tracing** |
12 |
| - |
13 |
| -> It currently uses AWS X-Ray |
14 |
| -
|
15 |
| -* Decorators that capture cold start as annotation, and response and exceptions as metadata |
16 |
| -* Run functions locally without code change to disable tracing |
17 |
| -* Explicitly disable tracing via env var `POWERTOOLS_TRACE_DISABLED="true"` |
18 |
| - |
19 |
| -**Logging** |
20 |
| - |
21 |
| -* Decorators that capture key fields from Lambda context, cold start and structures logging output as JSON |
22 |
| -* Optionally log Lambda request when instructed (disabled by default) |
23 |
| - - Enable via `POWERTOOLS_LOGGER_LOG_EVENT="true"` or explicitly via decorator param |
24 |
| -* Logs canonical custom metric line to logs that can be consumed asynchronously |
25 |
| -* Log sampling enables DEBUG log level for a percentage of requests (disabled by default) |
26 |
| - - Enable via `POWERTOOLS_LOGGER_SAMPLE_RATE=0.1`, ranges from 0 to 1, where 0.1 is 10% and 1 is 100% |
27 |
| - |
28 |
| -**Environment variables** used across suite of utilities |
29 |
| - |
30 |
| -Environment variable | Description | Default | Utility |
31 |
| -------------------------------------------------- | --------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- | ------------------------------------------------- |
32 |
| -POWERTOOLS_SERVICE_NAME | Sets service name used for tracing namespace, metrics dimensions and structured logging | "service_undefined" | all |
33 |
| -POWERTOOLS_TRACE_DISABLED | Disables tracing | "false" | tracing |
34 |
| -POWERTOOLS_LOGGER_LOG_EVENT | Logs incoming event | "false" | logging |
35 |
| -POWERTOOLS_LOGGER_SAMPLE_RATE | Debug log sampling | 0 | logging |
36 |
| -LOG_LEVEL | Sets logging level | "INFO" | logging |
37 |
| - |
38 |
| -## Usage |
39 |
| - |
40 |
| -### Installation |
41 |
| - |
42 |
| -With [pip](https://pip.pypa.io/en/latest/index.html) installed, run: ``pip install aws-lambda-powertools`` |
43 |
| - |
44 |
| -### Tracing |
45 |
| - |
46 |
| -**Example SAM template using supported environment variables** |
47 |
| - |
48 |
| -```yaml |
49 |
| -Globals: |
50 |
| - Function: |
51 |
| - Tracing: Active # can also be enabled per function |
52 |
| - Environment: |
53 |
| - Variables: |
54 |
| - POWERTOOLS_SERVICE_NAME: "payment" |
55 |
| - POWERTOOLS_TRACE_DISABLED: "false" |
56 |
| -``` |
57 |
| -
|
58 |
| -**Pseudo Python Lambda code** |
59 |
| -
|
60 |
| -```python |
61 |
| -from aws_lambda_powertools.tracing import Tracer |
62 |
| -tracer = Tracer() |
63 |
| -# tracer = Tracer(service="payment") # can also be explicitly defined |
64 |
| - |
65 |
| -@tracer.capture_method |
66 |
| -def collect_payment(charge_id): |
67 |
| - # logic |
68 |
| - ret = requests.post(PAYMENT_ENDPOINT) |
69 |
| - # custom annotation |
70 |
| - tracer.put_annotation("PAYMENT_STATUS", "SUCCESS") |
71 |
| - return ret |
72 |
| - |
73 |
| -@tracer.capture_lambda_handler |
74 |
| -def handler(event, context) |
75 |
| - charge_id = event.get('charge_id') |
76 |
| - payment = collect_payment(charge_id) |
77 |
| - ... |
78 |
| -``` |
79 |
| - |
80 |
| - |
81 |
| -### Logging |
82 |
| - |
83 |
| -**Example SAM template using supported environment variables** |
84 |
| - |
85 |
| -```yaml |
86 |
| -Globals: |
87 |
| - Function: |
88 |
| - Environment: |
89 |
| - Variables: |
90 |
| - POWERTOOLS_SERVICE_NAME: "payment" |
91 |
| - POWERTOOLS_LOGGER_SAMPLE_RATE: 0.1 # enable debug logging for 1% of requests, 0% by default |
92 |
| - LOG_LEVEL: "INFO" |
93 |
| -``` |
94 |
| -
|
95 |
| -**Pseudo Python Lambda code** |
96 |
| -
|
97 |
| -```python |
98 |
| -from aws_lambda_powertools.logging import logger_setup, logger_inject_lambda_context |
99 |
| - |
100 |
| -logger = logger_setup() |
101 |
| -# logger_setup(service="payment") # also accept explicit service name |
102 |
| -# logger_setup(level="INFO") # also accept explicit log level |
103 |
| - |
104 |
| -@logger_inject_lambda_context |
105 |
| -def handler(event, context) |
106 |
| - logger.info("Collecting payment") |
107 |
| - ... |
108 |
| - # You can log entire objects too |
109 |
| - logger.info({ |
110 |
| - "operation": "collect_payment", |
111 |
| - "charge_id": event['charge_id'] |
112 |
| - }) |
113 |
| - ... |
114 |
| -``` |
115 |
| - |
116 |
| -**Exerpt output in CloudWatch Logs** |
117 |
| - |
118 |
| -```json |
119 |
| -{ |
120 |
| - "timestamp":"2019-08-22 18:17:33,774", |
121 |
| - "level":"INFO", |
122 |
| - "location":"collect.handler:1", |
123 |
| - "service":"payment", |
124 |
| - "lambda_function_name":"test", |
125 |
| - "lambda_function_memory_size":"128", |
126 |
| - "lambda_function_arn":"arn:aws:lambda:eu-west-1:12345678910:function:test", |
127 |
| - "lambda_request_id":"52fdfc07-2182-154f-163f-5f0f9a621d72", |
128 |
| - "cold_start": "true", |
129 |
| - "message": "Collecting payment" |
130 |
| -} |
131 |
| - |
132 |
| -{ |
133 |
| - "timestamp":"2019-08-22 18:17:33,774", |
134 |
| - "level":"INFO", |
135 |
| - "location":"collect.handler:15", |
136 |
| - "service":"payment", |
137 |
| - "lambda_function_name":"test", |
138 |
| - "lambda_function_memory_size":"128", |
139 |
| - "lambda_function_arn":"arn:aws:lambda:eu-west-1:12345678910:function:test", |
140 |
| - "lambda_request_id":"52fdfc07-2182-154f-163f-5f0f9a621d72", |
141 |
| - "cold_start": "true", |
142 |
| - "message":{ |
143 |
| - "operation":"collect_payment", |
144 |
| - "charge_id": "ch_AZFlk2345C0" |
145 |
| - } |
146 |
| -} |
147 |
| -``` |
148 |
| - |
149 |
| -#### Custom Metrics async |
150 |
| - |
151 |
| -> **NOTE**: This will **likely change after Beta** in light of [new Amazon CloudWatch embedded metric format](https://aws.amazon.com/about-aws/whats-new/2019/11/amazon-cloudwatch-launches-embedded-metric-format/), meaning we won't need an additional stack and interface could change. |
152 |
| -
|
153 |
| -This feature requires [Custom Metrics SAR App](https://serverlessrepo.aws.amazon.com/applications/arn:aws:serverlessrepo:us-east-1:374852340823:applications~async-custom-metrics) in order to process canonical metric lines in CloudWatch Logs. |
154 |
| - |
155 |
| -If you're starting from scratch, you may want to see a working example, tune to your needs and deploy within your account - [Serverless Airline Log Processing Stack](https://github.com/aws-samples/aws-serverless-airline-booking/blob/develop/src/backend/log-processing/template.yaml) |
156 |
| - |
157 |
| -```python |
158 |
| -from aws_lambda_powertools.logging import MetricUnit, log_metric |
159 |
| - |
160 |
| -def handler(event, context) |
161 |
| - log_metric(name="SuccessfulPayment", unit=MetricUnit.Count, value=10, namespace="MyApplication") |
162 |
| - |
163 |
| - # Optional dimensions |
164 |
| - log_metric(name="SuccessfulPayment", unit=MetricUnit.Count, value=10, namespace="MyApplication", customer_id="123-abc", charge_id="abc-123") |
165 |
| - |
166 |
| - # Explicit service name |
167 |
| - log_metric(service="paymentTest", name="SuccessfulPayment", namespace="MyApplication".....) |
168 |
| - ... |
169 |
| -``` |
170 |
| - |
171 |
| -**Exerpt output in CloudWatch Logs** |
172 |
| - |
173 |
| -``` |
174 |
| -MONITORING|10|Count|SuccessfulPayment|MyApplication|service="payment |
175 |
| -MONITORING|10|Count|SuccessfulPayment|MyApplication|customer_id="123-abc",charge_id="abc-123",service="payment |
176 |
| -MONITORING|10|Count|SuccessfulPayment|MyApplication|service="paymentTest |
177 |
| -``` |
178 |
| - |
179 |
| - |
180 |
| -## Beta |
181 |
| - |
182 |
| -This library may change its API/methods or environment variables as it receives feedback from customers. Currently looking for ideas in the following areas before making it stable: |
183 |
| - |
184 |
| -* **Should Tracer patch all possible imported libraries by default or only AWS SDKs?** |
185 |
| - - Patching all libraries may have a small performance penalty (~50ms) at cold start |
186 |
| - - Alternatively, we could patch only AWS SDK if available and to provide a param to patch multiple `Tracer(modules=("boto3", "requests"))` |
187 |
| -* **Create a Tracer provider to support additional tracing** |
188 |
| - - Either duck typing or ABC to allow additional tracing providers |
189 |
| - |
190 |
| -## TODO |
191 |
| - |
192 |
| -* [ ] Add an example code using powertools |
| 9 | +* [Python - Beta](./python/README.md) |
193 | 10 |
|
194 | 11 | ## Credits
|
195 | 12 |
|
|
0 commit comments