Skip to content

Commit 00ee8dd

Browse files
heitorlessaTom McCarthy
and
Tom McCarthy
authored
fix: metrics not being flushed on every invocation (#45)
* [Sync Master] 0.7.0 release (#22) * docs: add pypi badge * fix: add missing single_metric example; test var name * chore: pypi monthly download badge * chore: fix github badge typo * feat: add docs to CI * fix: CI attempt 2 * fix: CI attempt 3 * fix: CI attempt 3 * fix: CI attempt 4 * chore: clean up CI workflows * Decorator factory Feat: Create your own middleware (#17) * feat(utils): add decorator factory * improv: use partial to reduce complexity * improv: add error handling * chore: type hint * docs: include pypi downloads badge * feat: opt in to trace each middleware that runs * improv: add initial util tests * improv: test explicit and implicit trace_execution * improv: test decorator with params * chore: linting * docs: include utilities * improv: correct tests, dec_factory only for func * improv: make util name more explicit * improv: doc trace_execution, fix casting * docs: add limitations, improve syntax * docs: use new docs syntax * fix: remove middleware decorator from libs * feat: build docs in CI * chore: linting * fix: CI python-version type * chore: remove docs CI * chore: kick CI * chore: include build badge master branch * chore: refactor naming * fix: rearrange tracing tests * improv(tracer): toggle default auto patching * feat(tracer): retrieve registered class instance * fix(Makefile): make cov target more explicit * improv(Register): support multiple classes reg. * improv(Register): inject class methods correctly * docs: add how to reutilize Tracer * improv(tracer): test auto patch method * improv: address nicolas feedback * improv: update example to reflect middleware feat * fix: metric dimension in root blob * chore: version bump Co-authored-by: heitorlessa <[email protected]> Co-authored-by: heitorlessa <[email protected]> * feat: add algolia search for docs and api ref (#39) (#40) Signed-off-by: heitorlessa <[email protected]> * fix: revert makefile build-docs-api Signed-off-by: heitorlessa <[email protected]> * fix: metric_set reuse #43 Signed-off-by: heitorlessa <[email protected]> * fix: clear metrics Signed-off-by: heitorlessa <[email protected]> * fix: update serialize_metrics helper function to use MetricManager instead of Metrics * fix: clear metrics after lambda invocation #43 Signed-off-by: heitorlessa <[email protected]> * improv: document metrics tests, remove redundants Signed-off-by: heitorlessa <[email protected]> #43 * chore: linting Signed-off-by: heitorlessa <[email protected]> * docs: add section to flush metrics manually Signed-off-by: heitorlessa <[email protected]> * docs: include EMF Json object Signed-off-by: heitorlessa <[email protected]> * chore: bump version 0.9.4 Signed-off-by: heitorlessa <[email protected]> Co-authored-by: Tom McCarthy <[email protected]>
1 parent 08f98da commit 00ee8dd

File tree

8 files changed

+171
-96
lines changed

8 files changed

+171
-96
lines changed

Diff for: CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# HISTORY
22

3+
## May 29th
4+
5+
**0.9.4**
6+
7+
* **Metrics**: Bugfix - Metrics were not correctly flushed, and cleared on every invocation
8+
39
## May 16th
410

511
**0.9.3**

Diff for: Makefile

+2-3
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,8 @@ build-docs:
3333
@$(MAKE) build-docs-website
3434
@$(MAKE) build-docs-api
3535

36-
build-docs-api:
37-
pip install pdoc3~=0.7.5
38-
pdoc3 --html --output-dir dist/api/ ./aws_lambda_powertools --force
36+
build-docs-api: dev
37+
poetry run pdoc --html --output-dir dist/api/ ./aws_lambda_powertools --force
3938
mv dist/api/aws_lambda_powertools/* dist/api/
4039
rm -rf dist/api/aws_lambda_powertools
4140

Diff for: aws_lambda_powertools/metrics/base.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ class MetricManager:
5050
"""
5151

5252
def __init__(self, metric_set: Dict[str, str] = None, dimension_set: Dict = None, namespace: str = None):
53-
self.metric_set = metric_set or {}
54-
self.dimension_set = dimension_set or {}
53+
self.metric_set = metric_set if metric_set is not None else {}
54+
self.dimension_set = dimension_set if dimension_set is not None else {}
5555
self.namespace = os.getenv("POWERTOOLS_METRICS_NAMESPACE") or namespace
5656
self._metric_units = [unit.value for unit in MetricUnit]
5757
self._metric_unit_options = list(MetricUnit.__members__)
@@ -116,7 +116,10 @@ def add_metric(self, name: str, unit: MetricUnit, value: Union[float, int]):
116116
logger.debug(f"Exceeded maximum of {MAX_METRICS} metrics - Publishing existing metric set")
117117
metrics = self.serialize_metric_set()
118118
print(json.dumps(metrics))
119-
self.metric_set = {}
119+
120+
# clear metric set only as opposed to metrics and dimensions set
121+
# since we could have more than 100 metrics
122+
self.metric_set.clear()
120123

121124
def serialize_metric_set(self, metrics: Dict = None, dimensions: Dict = None) -> Dict:
122125
"""Serializes metric and dimensions set

Diff for: aws_lambda_powertools/metrics/metrics.py

+10-2
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,15 @@ def do_something():
6565
_metrics = {}
6666
_dimensions = {}
6767

68-
def __init__(self, metric_set=None, dimension_set=None, namespace=None):
69-
super().__init__(metric_set=self._metrics, dimension_set=self._dimensions, namespace=namespace)
68+
def __init__(self):
69+
self.metric_set = self._metrics
70+
self.dimension_set = self._dimensions
71+
super().__init__(metric_set=self.metric_set, dimension_set=self.dimension_set)
72+
73+
def clear_metrics(self):
74+
logger.debug("Clearing out existing metric set from memory")
75+
self.metric_set.clear()
76+
self.dimension_set.clear()
7077

7178
def log_metrics(self, lambda_handler: Callable[[Any, Any], Any] = None):
7279
"""Decorator to serialize and publish metrics at the end of a function execution.
@@ -101,6 +108,7 @@ def decorate(*args, **kwargs):
101108
response = lambda_handler(*args, **kwargs)
102109
finally:
103110
metrics = self.serialize_metric_set()
111+
self.clear_metrics()
104112
logger.debug("Publishing metrics", {"metrics": metrics})
105113
print(json.dumps(metrics))
106114

Diff for: docs/content/core/metrics.mdx

+19
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,25 @@ def lambda_handler(evt, ctx):
122122
...
123123
```
124124

125+
## Flushing metrics manually
126+
127+
If you prefer not to use `log_metrics` because you might want to encapsulate additional logic when doing so, you can manually flush and clear metrics as follows:
128+
129+
```python:title=manual_metric_serialization.py
130+
import json
131+
from aws_lambda_powertools.metrics import Metrics, MetricUnit
132+
133+
metrics = Metrics()
134+
metrics.add_metric(name="ColdStart", unit="Count", value=1)
135+
metrics.add_dimension(name="service", value="booking")
136+
137+
# highlight-start
138+
your_metrics_object = metrics.serialize_metric_set()
139+
metrics.clear_metrics()
140+
print(json.dumps(your_metrics_object))
141+
# highlight-end
142+
```
143+
125144
## Testing your code
126145

127146
Use `POWERTOOLS_METRICS_NAMESPACE` env var when unit testing your code to ensure a metric namespace object is created, and your code doesn't fail validation.

Diff for: pyproject.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "aws_lambda_powertools"
3-
version = "0.9.3"
3+
version = "0.9.4"
44
description = "Python utilities for AWS Lambda functions including but not limited to tracing, logging and custom metric"
55
authors = ["Amazon Web Services"]
66
classifiers=[

0 commit comments

Comments
 (0)