Skip to content

Commit 7602e5e

Browse files
Refactoring Datadog provider with the new BaseProvider
2 parents 98f2f05 + 08a0a7b commit 7602e5e

24 files changed

+884
-927
lines changed

CHANGELOG.md

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -29,40 +29,42 @@
2929

3030
## Maintenance
3131

32-
* **ci:** enable protected branch auditing ([#2913](https://github.com/aws-powertools/powertools-lambda-python/issues/2913))
3332
* **ci:** group dependabot updates ([#2896](https://github.com/aws-powertools/powertools-lambda-python/issues/2896))
34-
* **deps:** bump github.com/aws/aws-sdk-go-v2/config from 1.18.28 to 1.18.29 in /layer/scripts/layer-balancer ([#2844](https://github.com/aws-powertools/powertools-lambda-python/issues/2844))
33+
* **ci:** enable protected branch auditing ([#2913](https://github.com/aws-powertools/powertools-lambda-python/issues/2913))
34+
* **deps:** bump the layer-balancer group in /layer/scripts/layer-balancer with 2 updates ([#2904](https://github.com/aws-powertools/powertools-lambda-python/issues/2904))
35+
* **deps:** bump slsa-framework/slsa-github-generator from 1.7.0 to 1.8.0 ([#2927](https://github.com/aws-powertools/powertools-lambda-python/issues/2927))
3536
* **deps:** bump squidfunk/mkdocs-material from `33e28bd` to `cd3a522` in /docs ([#2859](https://github.com/aws-powertools/powertools-lambda-python/issues/2859))
36-
* **deps:** bump github.com/aws/aws-sdk-go-v2/service/lambda from 1.37.1 to 1.38.0 in /layer/scripts/layer-balancer ([#2843](https://github.com/aws-powertools/powertools-lambda-python/issues/2843))
37+
* **deps:** bump github.com/aws/aws-sdk-go-v2/config from 1.18.28 to 1.18.29 in /layer/scripts/layer-balancer ([#2844](https://github.com/aws-powertools/powertools-lambda-python/issues/2844))
38+
* **deps:** bump github.com/aws/aws-sdk-go-v2/service/lambda from 1.38.0 to 1.38.1 in /layer/scripts/layer-balancer ([#2876](https://github.com/aws-powertools/powertools-lambda-python/issues/2876))
3739
* **deps:** bump github.com/aws/aws-sdk-go-v2/config from 1.18.30 to 1.18.31 in /layer/scripts/layer-balancer ([#2889](https://github.com/aws-powertools/powertools-lambda-python/issues/2889))
3840
* **deps:** bump github.com/aws/aws-sdk-go-v2 from 1.19.0 to 1.19.1 in /layer/scripts/layer-balancer ([#2877](https://github.com/aws-powertools/powertools-lambda-python/issues/2877))
3941
* **deps:** bump github.com/aws/aws-sdk-go-v2/service/lambda from 1.38.1 to 1.39.0 in /layer/scripts/layer-balancer ([#2890](https://github.com/aws-powertools/powertools-lambda-python/issues/2890))
40-
* **deps:** bump github.com/aws/aws-sdk-go-v2/service/lambda from 1.38.0 to 1.38.1 in /layer/scripts/layer-balancer ([#2876](https://github.com/aws-powertools/powertools-lambda-python/issues/2876))
41-
* **deps:** bump the layer-balancer group in /layer/scripts/layer-balancer with 2 updates ([#2904](https://github.com/aws-powertools/powertools-lambda-python/issues/2904))
42-
* **deps:** bump pydantic from 1.10.11 to 1.10.12 ([#2846](https://github.com/aws-powertools/powertools-lambda-python/issues/2846))
43-
* **deps:** bump slsa-framework/slsa-github-generator from 1.7.0 to 1.8.0 ([#2927](https://github.com/aws-powertools/powertools-lambda-python/issues/2927))
4442
* **deps:** bump github.com/aws/aws-sdk-go-v2/config from 1.18.29 to 1.18.30 in /layer/scripts/layer-balancer ([#2875](https://github.com/aws-powertools/powertools-lambda-python/issues/2875))
45-
* **deps-dev:** bump mypy-boto3-lambda from 1.28.11 to 1.28.15 ([#2878](https://github.com/aws-powertools/powertools-lambda-python/issues/2878))
43+
* **deps:** bump the layer-balancer group in /layer/scripts/layer-balancer with 3 updates ([#2933](https://github.com/aws-powertools/powertools-lambda-python/issues/2933))
44+
* **deps:** bump github.com/aws/aws-sdk-go-v2/service/lambda from 1.37.1 to 1.38.0 in /layer/scripts/layer-balancer ([#2843](https://github.com/aws-powertools/powertools-lambda-python/issues/2843))
45+
* **deps:** bump pydantic from 1.10.11 to 1.10.12 ([#2846](https://github.com/aws-powertools/powertools-lambda-python/issues/2846))
46+
* **deps-dev:** bump aws-cdk from 2.88.0 to 2.89.0 ([#2887](https://github.com/aws-powertools/powertools-lambda-python/issues/2887))
4647
* **deps-dev:** bump mypy-boto3-appconfigdata from 1.28.0 to 1.28.15 ([#2879](https://github.com/aws-powertools/powertools-lambda-python/issues/2879))
48+
* **deps-dev:** bump mypy-boto3-lambda from 1.28.11 to 1.28.15 ([#2878](https://github.com/aws-powertools/powertools-lambda-python/issues/2878))
4749
* **deps-dev:** bump mypy-boto3-xray from 1.28.0 to 1.28.15 ([#2881](https://github.com/aws-powertools/powertools-lambda-python/issues/2881))
48-
* **deps-dev:** bump mypy-boto3-logs from 1.28.1 to 1.28.15 ([#2880](https://github.com/aws-powertools/powertools-lambda-python/issues/2880))
4950
* **deps-dev:** bump mkdocs-material from 9.1.19 to 9.1.21 ([#2894](https://github.com/aws-powertools/powertools-lambda-python/issues/2894))
50-
* **deps-dev:** bump aws-cdk from 2.88.0 to 2.89.0 ([#2887](https://github.com/aws-powertools/powertools-lambda-python/issues/2887))
51-
* **deps-dev:** bump cfn-lint from 0.79.4 to 0.79.5 ([#2870](https://github.com/aws-powertools/powertools-lambda-python/issues/2870))
5251
* **deps-dev:** bump the boto-typing group with 11 updates ([#2901](https://github.com/aws-powertools/powertools-lambda-python/issues/2901))
52+
* **deps-dev:** bump mypy-boto3-logs from 1.28.1 to 1.28.15 ([#2880](https://github.com/aws-powertools/powertools-lambda-python/issues/2880))
53+
* **deps-dev:** bump cfn-lint from 0.79.4 to 0.79.5 ([#2870](https://github.com/aws-powertools/powertools-lambda-python/issues/2870))
54+
* **deps-dev:** bump cfn-lint from 0.79.5 to 0.79.6 ([#2899](https://github.com/aws-powertools/powertools-lambda-python/issues/2899))
5355
* **deps-dev:** bump mypy-boto3-cloudformation from 1.28.10 to 1.28.12 ([#2864](https://github.com/aws-powertools/powertools-lambda-python/issues/2864))
5456
* **deps-dev:** bump mypy-boto3-cloudwatch from 1.28.0 to 1.28.12 ([#2865](https://github.com/aws-powertools/powertools-lambda-python/issues/2865))
5557
* **deps-dev:** bump cfn-lint from 0.79.3 to 0.79.4 ([#2862](https://github.com/aws-powertools/powertools-lambda-python/issues/2862))
5658
* **deps-dev:** bump mypy-boto3-appconfig from 1.28.0 to 1.28.12 ([#2861](https://github.com/aws-powertools/powertools-lambda-python/issues/2861))
5759
* **deps-dev:** bump mypy-boto3-ssm from 1.28.0 to 1.28.12 ([#2863](https://github.com/aws-powertools/powertools-lambda-python/issues/2863))
58-
* **deps-dev:** bump cfn-lint from 0.79.5 to 0.79.6 ([#2899](https://github.com/aws-powertools/powertools-lambda-python/issues/2899))
5960
* **deps-dev:** bump sentry-sdk from 1.28.1 to 1.29.0 ([#2900](https://github.com/aws-powertools/powertools-lambda-python/issues/2900))
60-
* **deps-dev:** bump cfn-lint from 0.78.2 to 0.79.3 ([#2854](https://github.com/aws-powertools/powertools-lambda-python/issues/2854))
61-
* **deps-dev:** bump mypy-boto3-lambda from 1.28.0 to 1.28.11 ([#2845](https://github.com/aws-powertools/powertools-lambda-python/issues/2845))
6261
* **deps-dev:** bump ruff from 0.0.280 to 0.0.281 ([#2891](https://github.com/aws-powertools/powertools-lambda-python/issues/2891))
62+
* **deps-dev:** bump cfn-lint from 0.78.2 to 0.79.3 ([#2854](https://github.com/aws-powertools/powertools-lambda-python/issues/2854))
6363
* **deps-dev:** bump ruff from 0.0.281 to 0.0.282 ([#2905](https://github.com/aws-powertools/powertools-lambda-python/issues/2905))
64-
* **deps-dev:** bump mypy-boto3-dynamodb from 1.28.0 to 1.28.11 ([#2847](https://github.com/aws-powertools/powertools-lambda-python/issues/2847))
6564
* **deps-dev:** bump the boto-typing group with 4 updates ([#2928](https://github.com/aws-powertools/powertools-lambda-python/issues/2928))
65+
* **deps-dev:** bump aws-cdk from 2.89.0 to 2.90.0 ([#2932](https://github.com/aws-powertools/powertools-lambda-python/issues/2932))
66+
* **deps-dev:** bump mypy-boto3-dynamodb from 1.28.0 to 1.28.11 ([#2847](https://github.com/aws-powertools/powertools-lambda-python/issues/2847))
67+
* **deps-dev:** bump mypy-boto3-lambda from 1.28.0 to 1.28.11 ([#2845](https://github.com/aws-powertools/powertools-lambda-python/issues/2845))
6668
* **docs:** disable line length rule using older syntax ([#2920](https://github.com/aws-powertools/powertools-lambda-python/issues/2920))
6769
* **maintenance:** enables publishing docs and changelog, running e2e tests only in the main repository ([#2924](https://github.com/aws-powertools/powertools-lambda-python/issues/2924))
6870

aws_lambda_powertools/metrics/base.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@
1717
MetricValueError,
1818
SchemaValidationError,
1919
)
20-
from aws_lambda_powertools.metrics.provider.cloudwatch_emf import cold_start
21-
from aws_lambda_powertools.metrics.provider.cloudwatch_emf.cold_start import (
22-
reset_cold_start_flag, # noqa: F401 # backwards compatibility
23-
)
20+
from aws_lambda_powertools.metrics.provider import cold_start
2421
from aws_lambda_powertools.metrics.provider.cloudwatch_emf.constants import MAX_DIMENSIONS, MAX_METRICS
2522
from aws_lambda_powertools.metrics.provider.cloudwatch_emf.metric_properties import MetricResolution, MetricUnit
23+
from aws_lambda_powertools.metrics.provider.cold_start import (
24+
reset_cold_start_flag, # noqa: F401 # backwards compatibility
25+
)
2626
from aws_lambda_powertools.metrics.types import MetricNameUnitResolution
2727
from aws_lambda_powertools.shared import constants
2828
from aws_lambda_powertools.shared.functions import resolve_env_var_choice
Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,16 @@
1-
from aws_lambda_powertools.metrics.provider.base.exceptions import MetricValueError, SchemaValidationError
21
from aws_lambda_powertools.metrics.provider.cloudwatch_emf.exceptions import MetricResolutionError, MetricUnitError
32

3+
4+
class SchemaValidationError(Exception):
5+
"""When serialization fail schema validation"""
6+
7+
pass
8+
9+
10+
class MetricValueError(Exception):
11+
"""When metric value isn't a valid number"""
12+
13+
pass
14+
15+
416
__all__ = ["MetricUnitError", "MetricResolutionError", "SchemaValidationError", "MetricValueError"]
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
from __future__ import annotations
2+
3+
from typing import List
4+
5+
from aws_lambda_powertools.metrics.provider.cloudwatch_emf.exceptions import (
6+
MetricResolutionError,
7+
MetricUnitError,
8+
)
9+
from aws_lambda_powertools.metrics.provider.cloudwatch_emf.metric_properties import MetricResolution, MetricUnit
10+
11+
12+
def extract_cloudwatch_metric_resolution_value(metric_resolutions: List, resolution: int | MetricResolution) -> int:
13+
"""Return metric value from CloudWatch metric unit whether that's str or MetricResolution enum
14+
15+
Parameters
16+
----------
17+
unit : Union[int, MetricResolution]
18+
Metric resolution
19+
20+
Returns
21+
-------
22+
int
23+
Metric resolution value must be 1 or 60
24+
25+
Raises
26+
------
27+
MetricResolutionError
28+
When metric resolution is not supported by CloudWatch
29+
"""
30+
if isinstance(resolution, MetricResolution):
31+
return resolution.value
32+
33+
if isinstance(resolution, int) and resolution in metric_resolutions:
34+
return resolution
35+
36+
raise MetricResolutionError(
37+
f"Invalid metric resolution '{resolution}', expected either option: {metric_resolutions}", # noqa: E501
38+
)
39+
40+
41+
def extract_cloudwatch_metric_unit_value(metric_units: List, metric_valid_options: List, unit: str | MetricUnit) -> str:
42+
"""Return metric value from CloudWatch metric unit whether that's str or MetricUnit enum
43+
44+
Parameters
45+
----------
46+
unit : Union[str, MetricUnit]
47+
Metric unit
48+
49+
Returns
50+
-------
51+
str
52+
Metric unit value (e.g. "Seconds", "Count/Second")
53+
54+
Raises
55+
------
56+
MetricUnitError
57+
When metric unit is not supported by CloudWatch
58+
"""
59+
60+
if isinstance(unit, str):
61+
if unit in metric_valid_options:
62+
unit = MetricUnit[unit].value
63+
64+
if unit not in metric_units:
65+
raise MetricUnitError(
66+
f"Invalid metric unit '{unit}', expected either option: {metric_valid_options}",
67+
)
68+
69+
if isinstance(unit, MetricUnit):
70+
unit = unit.value
71+
72+
return unit

aws_lambda_powertools/metrics/metrics.py

Lines changed: 4 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
# NOTE: keeps for compatibility
22
from __future__ import annotations
33

4-
from typing import Any, Callable, Dict, Optional, Union
4+
from typing import Any, Callable, Dict, Optional
55

66
from aws_lambda_powertools.metrics.base import MetricResolution, MetricUnit
77
from aws_lambda_powertools.metrics.provider.cloudwatch_emf.cloudwatch import AmazonCloudWatchEMFProvider
8+
from aws_lambda_powertools.metrics.provider.cloudwatch_emf.types import CloudWatchEMFOutput
89

910

1011
class Metrics:
11-
"""Metrics create an EMF object with up to 100 metrics
12+
"""Metrics create an CloudWatch EMF object with up to 100 metrics
1213
1314
Use Metrics when you need to create multiple metrics that have
1415
dimensions in common (e.g. service_name="payment").
@@ -115,7 +116,7 @@ def serialize_metric_set(
115116
metrics: Dict | None = None,
116117
dimensions: Dict | None = None,
117118
metadata: Dict | None = None,
118-
) -> Dict:
119+
) -> CloudWatchEMFOutput:
119120
return self.provider.serialize_metric_set(metrics=metrics, dimensions=dimensions, metadata=metadata)
120121

121122
def add_metadata(self, key: str, value: Any) -> None:
@@ -138,15 +139,6 @@ def log_metrics(
138139
default_dimensions=default_dimensions,
139140
)
140141

141-
def _extract_metric_resolution_value(self, resolution: Union[int, MetricResolution]) -> int:
142-
return self.provider._extract_metric_resolution_value(resolution=resolution)
143-
144-
def _extract_metric_unit_value(self, unit: Union[str, MetricUnit]) -> str:
145-
return self.provider._extract_metric_unit_value(unit=unit)
146-
147-
def _add_cold_start_metric(self, context: Any) -> None:
148-
self.provider._add_cold_start_metric(context=context)
149-
150142
def set_default_dimensions(self, **dimensions) -> None:
151143
self.provider.set_default_dimensions(**dimensions)
152144
"""Persist dimensions across Lambda invocations
@@ -208,120 +200,3 @@ def service(self, service):
208200
# we can quickly revert and duplicate code while using self.provider
209201

210202
EphemeralMetrics = AmazonCloudWatchEMFProvider
211-
212-
# noqa: ERA001
213-
# class EphemeralMetrics(MetricManager):
214-
# """Non-singleton version of Metrics to not persist metrics across instances
215-
#
216-
# NOTE: This is useful when you want to:
217-
#
218-
# - Create metrics for distinct namespaces
219-
# - Create the same metrics with different dimensions more than once
220-
# """
221-
#
222-
# # _dimensions: Dict[str, str] = {}
223-
# _default_dimensions: Dict[str, Any] = {}
224-
#
225-
# def __init__(
226-
# self,
227-
# service: str | None = None,
228-
# namespace: str | None = None,
229-
# provider: AmazonCloudWatchEMFProvider | None = None,
230-
# ):
231-
# super().__init__(namespace=namespace, service=service)
232-
#
233-
# self.default_dimensions = self._default_dimensions
234-
# # # self.dimension_set = self._dimensions
235-
# # self.dimension_set.update(**self._default_dimensions)
236-
#
237-
# self.provider = provider or AmazonCloudWatchEMFProvider(
238-
# namespace=namespace,
239-
# service=service,
240-
# metric_set=self.metric_set,
241-
# metadata_set=self.metadata_set,
242-
# dimension_set=self.dimension_set,
243-
# default_dimensions=self._default_dimensions,
244-
# )
245-
#
246-
# def add_metric(
247-
# self,
248-
# name: str,
249-
# unit: MetricUnit | str,
250-
# value: float,
251-
# resolution: MetricResolution | int = 60,
252-
# ) -> None:
253-
# return self.provider.add_metric(name=name, unit=unit, value=value, resolution=resolution)
254-
#
255-
# def add_dimension(self, name: str, value: str) -> None:
256-
# return self.provider.add_dimension(name=name, value=value)
257-
#
258-
# def serialize_metric_set(
259-
# self,
260-
# metrics: Dict | None = None,
261-
# dimensions: Dict | None = None,
262-
# metadata: Dict | None = None,
263-
# ) -> Dict:
264-
# return self.provider.serialize_metric_set(metrics=metrics, dimensions=dimensions, metadata=metadata)
265-
#
266-
# def add_metadata(self, key: str, value: Any) -> None:
267-
# self.provider.add_metadata(key=key, value=value)
268-
#
269-
# def flush_metrics(self, raise_on_empty_metrics: bool = False) -> None:
270-
# self.provider.flush_metrics(raise_on_empty_metrics=raise_on_empty_metrics)
271-
#
272-
# def log_metrics(
273-
# self,
274-
# lambda_handler: Callable[[Dict, Any], Any] | Optional[Callable[[Dict, Any, Optional[Dict]], Any]] = None,
275-
# capture_cold_start_metric: bool = False,
276-
# raise_on_empty_metrics: bool = False,
277-
# default_dimensions: Dict[str, str] | None = None,
278-
# ):
279-
# return self.provider.log_metrics(
280-
# lambda_handler=lambda_handler,
281-
# capture_cold_start_metric=capture_cold_start_metric,
282-
# raise_on_empty_metrics=raise_on_empty_metrics,
283-
# default_dimensions=default_dimensions,
284-
# )
285-
#
286-
# def _extract_metric_resolution_value(self, resolution: Union[int, MetricResolution]) -> int:
287-
# return self.provider._extract_metric_resolution_value(resolution=resolution)
288-
#
289-
# def _extract_metric_unit_value(self, unit: Union[str, MetricUnit]) -> str:
290-
# return self.provider._extract_metric_unit_value(unit=unit)
291-
#
292-
# def _add_cold_start_metric(self, context: Any) -> None:
293-
# return self.provider._add_cold_start_metric(context=context)
294-
#
295-
# def set_default_dimensions(self, **dimensions) -> None:
296-
# """Persist dimensions across Lambda invocations
297-
#
298-
# Parameters
299-
# ----------
300-
# dimensions : Dict[str, Any], optional
301-
# metric dimensions as key=value
302-
#
303-
# Example
304-
# -------
305-
# **Sets some default dimensions that will always be present across metrics and invocations**
306-
#
307-
# from aws_lambda_powertools import Metrics
308-
#
309-
# metrics = Metrics(namespace="ServerlessAirline", service="payment")
310-
# metrics.set_default_dimensions(environment="demo", another="one")
311-
#
312-
# @metrics.log_metrics()
313-
# def lambda_handler():
314-
# return True
315-
# """
316-
# return self.provider.set_default_dimensions(**dimensions)
317-
#
318-
# def clear_default_dimensions(self) -> None:
319-
# self.default_dimensions.clear()
320-
#
321-
# def clear_metrics(self) -> None:
322-
# self.provider.clear_metrics()
323-
# # re-add default dimensions
324-
# self.set_default_dimensions(**self.default_dimensions)
325-
#
326-
327-
# __all__ = []
Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
1-
from aws_lambda_powertools.metrics.provider.base import MetricsBase, MetricsProviderBase
2-
from aws_lambda_powertools.metrics.provider.datadog import DatadogMetrics, DatadogProvider
1+
from aws_lambda_powertools.metrics.provider.base import BaseProvider
32

43
__all__ = [
5-
"MetricsBase",
6-
"MetricsProviderBase",
7-
"DatadogMetrics",
8-
"DatadogProvider",
4+
"BaseProvider",
95
]

0 commit comments

Comments
 (0)