Skip to content

refactor(metrics): move from protocol to ABC; split provider tests #2934

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

Merged
merged 12 commits into from
Aug 9, 2023
Prev Previous commit
Next Next commit
Making function standalone
  • Loading branch information
leandrodamascena committed Aug 7, 2023
commit a7e85acfcb25e17165717cc2db98879a40db32af
8 changes: 1 addition & 7 deletions aws_lambda_powertools/metrics/metrics.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# NOTE: keeps for compatibility
from __future__ import annotations

from typing import Any, Callable, Dict, Optional, Union
from typing import Any, Callable, Dict, Optional

from aws_lambda_powertools.metrics.base import MetricResolution, MetricUnit
from aws_lambda_powertools.metrics.provider.cloudwatch_emf.cloudwatch import AmazonCloudWatchEMFProvider
Expand Down Expand Up @@ -138,12 +138,6 @@ def log_metrics(
default_dimensions=default_dimensions,
)

def _extract_metric_resolution_value(self, resolution: Union[int, MetricResolution]) -> int:
return self.provider._extract_metric_resolution_value(resolution=resolution)

def _extract_metric_unit_value(self, unit: Union[str, MetricUnit]) -> str:
return self.provider._extract_metric_unit_value(unit=unit)

def _add_cold_start_metric(self, context: Any) -> None:
self.provider._add_cold_start_metric(context=context)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,18 @@
import os
import warnings
from collections import defaultdict
from typing import Any, Callable, Dict, List, Optional, Union
from typing import Any, Callable, Dict, List, Optional

from aws_lambda_powertools.metrics.base import single_metric
from aws_lambda_powertools.metrics.exceptions import MetricValueError, SchemaValidationError
from aws_lambda_powertools.metrics.provider import MetricsProviderBase
from aws_lambda_powertools.metrics.provider.cloudwatch_emf import cold_start
from aws_lambda_powertools.metrics.provider.cloudwatch_emf.constants import MAX_DIMENSIONS, MAX_METRICS
from aws_lambda_powertools.metrics.provider.cloudwatch_emf.exceptions import (
MetricResolutionError,
MetricUnitError,
)
from aws_lambda_powertools.metrics.provider.cloudwatch_emf.metric_properties import MetricResolution, MetricUnit
from aws_lambda_powertools.metrics.shared import (
extract_cloudwatch_metric_resolution_value,
extract_cloudwatch_metric_unit_value,
)
from aws_lambda_powertools.metrics.types import MetricNameUnitResolution
from aws_lambda_powertools.shared import constants
from aws_lambda_powertools.shared.functions import resolve_env_var_choice
Expand Down Expand Up @@ -123,8 +123,15 @@ def add_metric(
if not isinstance(value, numbers.Number):
raise MetricValueError(f"{value} is not a valid number")

unit = self._extract_metric_unit_value(unit=unit)
resolution = self._extract_metric_resolution_value(resolution=resolution)
unit = extract_cloudwatch_metric_unit_value(
metric_units=self._metric_units,
metric_valid_options=self._metric_unit_valid_options,
unit=unit,
)
resolution = extract_cloudwatch_metric_resolution_value(
metric_resolutions=self._metric_resolutions,
resolution=resolution,
)
metric: Dict = self.metric_set.get(name, defaultdict(list))
metric["Unit"] = unit
metric["StorageResolution"] = resolution
Expand Down Expand Up @@ -392,67 +399,6 @@ def decorate(event, context):

return decorate

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

Parameters
----------
unit : Union[int, MetricResolution]
Metric resolution

Returns
-------
int
Metric resolution value must be 1 or 60

Raises
------
MetricResolutionError
When metric resolution is not supported by CloudWatch
"""
if isinstance(resolution, MetricResolution):
return resolution.value

if isinstance(resolution, int) and resolution in self._metric_resolutions:
return resolution

raise MetricResolutionError(
f"Invalid metric resolution '{resolution}', expected either option: {self._metric_resolutions}", # noqa: E501
)

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_valid_options:
unit = MetricUnit[unit].value

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

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

return unit

def _add_cold_start_metric(self, context: Any) -> None:
"""Add cold start metric and function_name dimension

Expand Down
72 changes: 72 additions & 0 deletions aws_lambda_powertools/metrics/shared.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
from __future__ import annotations

from typing import List

from aws_lambda_powertools.metrics.provider.cloudwatch_emf.exceptions import (
MetricResolutionError,
MetricUnitError,
)
from aws_lambda_powertools.metrics.provider.cloudwatch_emf.metric_properties import MetricResolution, MetricUnit


def extract_cloudwatch_metric_resolution_value(metric_resolutions: List, resolution: int | MetricResolution) -> int:
"""Return metric value from CloudWatch metric unit whether that's str or MetricResolution enum

Parameters
----------
unit : Union[int, MetricResolution]
Metric resolution

Returns
-------
int
Metric resolution value must be 1 or 60

Raises
------
MetricResolutionError
When metric resolution is not supported by CloudWatch
"""
if isinstance(resolution, MetricResolution):
return resolution.value

if isinstance(resolution, int) and resolution in metric_resolutions:
return resolution

raise MetricResolutionError(
f"Invalid metric resolution '{resolution}', expected either option: {metric_resolutions}", # noqa: E501
)


def extract_cloudwatch_metric_unit_value(metric_units: List, metric_valid_options: List, unit: str | MetricUnit) -> str:
"""Return metric value from CloudWatch 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 metric_valid_options:
unit = MetricUnit[unit].value

if unit not in metric_units:
raise MetricUnitError(
f"Invalid metric unit '{unit}', expected either option: {metric_valid_options}",
)

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

return unit