Skip to content

Commit aa9980e

Browse files
authored
Bugfix: "per second" metric units (#27)
* improv: test all metric units * fix: correct MetricUnit model values * fix: metric unit as string branch logic * chore: refactor * chore: test str * chore: bump version with metric unit patch Co-authored-by: heitorlessa <[email protected]>
1 parent a8c74e7 commit aa9980e

File tree

5 files changed

+94
-20
lines changed

5 files changed

+94
-20
lines changed

Diff for: python/HISTORY.md

+20
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,27 @@
11
# HISTORY
22

3+
## May 1st
4+
5+
**0.8.1**
6+
7+
* Fix metric unit casting logic if one passes plain string (value or key)
8+
* Fix `MetricUnit` enum values for
9+
- `BytesPerSecond`
10+
- `KilobytesPerSecond`
11+
- `MegabytesPerSecond`
12+
- `GigabytesPerSecond`
13+
- `TerabytesPerSecond`
14+
- `BitsPerSecond`
15+
- `KilobitsPerSecond`
16+
- `MegabitsPerSecond`
17+
- `GigabitsPerSecond`
18+
- `TerabitsPerSecond`
19+
- `CountPerSecond`
20+
321
## April 24th
422

23+
**0.8.0**
24+
525
* Introduces `Logger` for stuctured logging as a replacement for `logger_setup`
626
* Introduces `Logger.inject_lambda_context` decorator as a replacement for `logger_inject_lambda_context`
727
* Raise `DeprecationWarning` exception for both `logger_setup`, `logger_inject_lambda_context`

Diff for: python/aws_lambda_powertools/helper/models.py

+11-11
Original file line numberDiff line numberDiff line change
@@ -89,17 +89,17 @@ class MetricUnit(Enum):
8989
Terabits = "Terabits"
9090
Percent = "Percent"
9191
Count = "Count"
92-
BytesPerSecond = "Second"
93-
KilobytesPerSecond = "Second"
94-
MegabytesPerSecond = "Second"
95-
GigabytesPerSecond = "Second"
96-
TerabytesPerSecond = "Second"
97-
BitsPerSecond = "Second"
98-
KilobitsPerSecond = "Second"
99-
MegabitsPerSecond = "Second"
100-
GigabitsPerSecond = "Second"
101-
TerabitsPerSecond = "Second"
102-
CountPerSecond = "Second"
92+
BytesPerSecond = "Bytes/Second"
93+
KilobytesPerSecond = "Kilobytes/Second"
94+
MegabytesPerSecond = "Megabytes/Second"
95+
GigabytesPerSecond = "Gigabytes/Second"
96+
TerabytesPerSecond = "Terabytes/Second"
97+
BitsPerSecond = "Bits/Second"
98+
KilobitsPerSecond = "Kilobits/Second"
99+
MegabitsPerSecond = "Megabits/Second"
100+
GigabitsPerSecond = "Gigabits/Second"
101+
TerabitsPerSecond = "Terabits/Second"
102+
CountPerSecond = "Count/Second"
103103

104104

105105
def build_metric_unit_from_str(unit: Union[str, MetricUnit]) -> MetricUnit:

Diff for: python/aws_lambda_powertools/metrics/base.py

+37-8
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ def __init__(self, metric_set: Dict[str, str] = None, dimension_set: Dict = None
5353
self.metric_set = metric_set or {}
5454
self.dimension_set = dimension_set or {}
5555
self.namespace = os.getenv("POWERTOOLS_METRICS_NAMESPACE") or namespace
56+
self._metric_units = [unit.value for unit in MetricUnit]
57+
self._metric_unit_options = list(MetricUnit.__members__)
5658

5759
def add_namespace(self, name: str):
5860
"""Adds given metric namespace
@@ -105,14 +107,8 @@ def add_metric(self, name: str, unit: MetricUnit, value: Union[float, int]):
105107
if not isinstance(value, numbers.Number):
106108
raise MetricValueError(f"{value} is not a valid number")
107109

108-
if not isinstance(unit, MetricUnit):
109-
try:
110-
unit = MetricUnit[unit]
111-
except KeyError:
112-
unit_options = list(MetricUnit.__members__)
113-
raise MetricUnitError(f"Invalid metric unit '{unit}', expected either option: {unit_options}")
114-
115-
metric = {"Unit": unit.value, "Value": float(value)}
110+
unit = self.__extract_metric_unit_value(unit=unit)
111+
metric = {"Unit": unit, "Value": float(value)}
116112
logger.debug(f"Adding metric: {name} with {metric}")
117113
self.metric_set[name] = metric
118114

@@ -205,3 +201,36 @@ def add_dimension(self, name: str, value: str):
205201
"""
206202
logger.debug(f"Adding dimension: {name}:{value}")
207203
self.dimension_set[name] = value
204+
205+
def __extract_metric_unit_value(self, unit: Union[str, MetricUnit]) -> str:
206+
"""Return metric value from metric unit whether that's str or MetricUnit enum
207+
208+
Parameters
209+
----------
210+
unit : Union[str, MetricUnit]
211+
Metric unit
212+
213+
Returns
214+
-------
215+
str
216+
Metric unit value (e.g. "Seconds", "Count/Second")
217+
218+
Raises
219+
------
220+
MetricUnitError
221+
When metric unit is not supported by CloudWatch
222+
"""
223+
224+
if isinstance(unit, str):
225+
if unit in self._metric_unit_options:
226+
unit = MetricUnit[unit].value
227+
228+
if unit not in self._metric_units: # str correta
229+
raise MetricUnitError(
230+
f"Invalid metric unit '{unit}', expected either option: {self._metric_unit_options}"
231+
)
232+
233+
if isinstance(unit, MetricUnit):
234+
unit = unit.value
235+
236+
return unit

Diff for: python/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.8.0"
3+
version = "0.8.1"
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=[

Diff for: python/tests/functional/test_metrics.py

+25
Original file line numberDiff line numberDiff line change
@@ -303,3 +303,28 @@ def lambda_handler(evt, context):
303303

304304
with pytest.raises(SchemaValidationError):
305305
lambda_handler({}, {})
306+
307+
308+
def test_all_metric_units_string(metric, dimension, namespace):
309+
310+
# metric unit as MetricUnit key e.g. "Seconds", "BytesPerSecond"
311+
for unit in MetricUnit:
312+
metric["unit"] = unit.name
313+
with single_metric(**metric) as my_metric:
314+
my_metric.add_dimension(**dimension)
315+
my_metric.add_namespace(**namespace)
316+
317+
with pytest.raises(MetricUnitError):
318+
metric["unit"] = "seconds"
319+
with single_metric(**metric) as my_metric:
320+
my_metric.add_dimension(**dimension)
321+
my_metric.add_namespace(**namespace)
322+
323+
all_metric_units = [unit.value for unit in MetricUnit]
324+
325+
# metric unit as MetricUnit value e.g. "Seconds", "Bytes/Second"
326+
for unit in all_metric_units:
327+
metric["unit"] = unit
328+
with single_metric(**metric) as my_metric:
329+
my_metric.add_dimension(**dimension)
330+
my_metric.add_namespace(**namespace)

0 commit comments

Comments
 (0)