Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: metrics "per second" metric units #27

Merged
merged 6 commits into from
May 1, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions python/HISTORY.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,27 @@
# HISTORY

## May 1st

**0.8.1**

* Fix metric unit casting logic if one passes plain string (value or key)
* Fix `MetricUnit` enum values for
- `BytesPerSecond`
- `KilobytesPerSecond`
- `MegabytesPerSecond`
- `GigabytesPerSecond`
- `TerabytesPerSecond`
- `BitsPerSecond`
- `KilobitsPerSecond`
- `MegabitsPerSecond`
- `GigabitsPerSecond`
- `TerabitsPerSecond`
- `CountPerSecond`

## April 24th

**0.8.0**

* Introduces `Logger` for stuctured logging as a replacement for `logger_setup`
* Introduces `Logger.inject_lambda_context` decorator as a replacement for `logger_inject_lambda_context`
* Raise `DeprecationWarning` exception for both `logger_setup`, `logger_inject_lambda_context`
Expand Down
22 changes: 11 additions & 11 deletions python/aws_lambda_powertools/helper/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,17 +89,17 @@ class MetricUnit(Enum):
Terabits = "Terabits"
Percent = "Percent"
Count = "Count"
BytesPerSecond = "Second"
KilobytesPerSecond = "Second"
MegabytesPerSecond = "Second"
GigabytesPerSecond = "Second"
TerabytesPerSecond = "Second"
BitsPerSecond = "Second"
KilobitsPerSecond = "Second"
MegabitsPerSecond = "Second"
GigabitsPerSecond = "Second"
TerabitsPerSecond = "Second"
CountPerSecond = "Second"
BytesPerSecond = "Bytes/Second"
KilobytesPerSecond = "Kilobytes/Second"
MegabytesPerSecond = "Megabytes/Second"
GigabytesPerSecond = "Gigabytes/Second"
TerabytesPerSecond = "Terabytes/Second"
BitsPerSecond = "Bits/Second"
KilobitsPerSecond = "Kilobits/Second"
MegabitsPerSecond = "Megabits/Second"
GigabitsPerSecond = "Gigabits/Second"
TerabitsPerSecond = "Terabits/Second"
CountPerSecond = "Count/Second"


def build_metric_unit_from_str(unit: Union[str, MetricUnit]) -> MetricUnit:
Expand Down
45 changes: 37 additions & 8 deletions python/aws_lambda_powertools/metrics/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ def __init__(self, metric_set: Dict[str, str] = None, dimension_set: Dict = None
self.metric_set = metric_set or {}
self.dimension_set = dimension_set or {}
self.namespace = os.getenv("POWERTOOLS_METRICS_NAMESPACE") or namespace
self._metric_units = [unit.value for unit in MetricUnit]
self._metric_unit_options = list(MetricUnit.__members__)

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

if not isinstance(unit, MetricUnit):
try:
unit = MetricUnit[unit]
except KeyError:
unit_options = list(MetricUnit.__members__)
raise MetricUnitError(f"Invalid metric unit '{unit}', expected either option: {unit_options}")

metric = {"Unit": unit.value, "Value": float(value)}
unit = self.__extract_metric_unit_value(unit=unit)
metric = {"Unit": unit, "Value": float(value)}
logger.debug(f"Adding metric: {name} with {metric}")
self.metric_set[name] = metric

Expand Down Expand Up @@ -205,3 +201,36 @@ def add_dimension(self, name: str, value: str):
"""
logger.debug(f"Adding dimension: {name}:{value}")
self.dimension_set[name] = value

def __extract_metric_unit_value(self, unit: Union[str, MetricUnit]) -> str:
"""Return metric value from metric unit whether that's str or MetricUnit enum

Parameters
----------
unit : Union[str, MetricUnit]
Metric unit

Returns
-------
str
Metric unit value (e.g. "Seconds", "Count/Second")

Raises
------
MetricUnitError
When metric unit is not supported by CloudWatch
"""

if isinstance(unit, str):
if unit in self._metric_unit_options:
unit = MetricUnit[unit].value

if unit not in self._metric_units: # str correta
raise MetricUnitError(
f"Invalid metric unit '{unit}', expected either option: {self._metric_unit_options}"
)

if isinstance(unit, MetricUnit):
unit = unit.value

return unit
2 changes: 1 addition & 1 deletion python/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "aws_lambda_powertools"
version = "0.8.0"
version = "0.8.1"
description = "Python utilities for AWS Lambda functions including but not limited to tracing, logging and custom metric"
authors = ["Amazon Web Services"]
classifiers=[
Expand Down
25 changes: 25 additions & 0 deletions python/tests/functional/test_metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -303,3 +303,28 @@ def lambda_handler(evt, context):

with pytest.raises(SchemaValidationError):
lambda_handler({}, {})


def test_all_metric_units_string(metric, dimension, namespace):

# metric unit as MetricUnit key e.g. "Seconds", "BytesPerSecond"
for unit in MetricUnit:
metric["unit"] = unit.name
with single_metric(**metric) as my_metric:
my_metric.add_dimension(**dimension)
my_metric.add_namespace(**namespace)

with pytest.raises(MetricUnitError):
metric["unit"] = "seconds"
with single_metric(**metric) as my_metric:
my_metric.add_dimension(**dimension)
my_metric.add_namespace(**namespace)

all_metric_units = [unit.value for unit in MetricUnit]

# metric unit as MetricUnit value e.g. "Seconds", "Bytes/Second"
for unit in all_metric_units:
metric["unit"] = unit
with single_metric(**metric) as my_metric:
my_metric.add_dimension(**dimension)
my_metric.add_namespace(**namespace)