Skip to content
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
9 changes: 8 additions & 1 deletion aws_lambda_powertools/metrics/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,14 @@ def add_dimension(self, name: str, value: str):
Dimension value
"""
logger.debug(f"Adding dimension: {name}:{value}")
self.dimension_set[name] = value

# Cast value to str according to EMF spec
# Majority of values are expected to be string already, so
# checking before casting improves performance in most cases
if isinstance(value, str):
self.dimension_set[name] = value
else:
self.dimension_set[name] = str(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
Expand Down
34 changes: 33 additions & 1 deletion tests/functional/test_metrics.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import json
from typing import Dict, List
from typing import Any, Dict, List

import pytest

Expand Down Expand Up @@ -48,6 +48,14 @@ def dimensions() -> List[Dict[str, str]]:
]


@pytest.fixture
def non_str_dimensions() -> List[Dict[str, Any]]:
return [
{"name": "test_dimension", "value": True},
{"name": "test_dimension_2", "value": 3},
]


@pytest.fixture
def namespace() -> Dict[str, str]:
return {"name": "test_namespace"}
Expand Down Expand Up @@ -380,3 +388,27 @@ def lambda_handler(evt, context):

# THEN metric set should be empty after function has been run
assert my_metrics.metric_set == {}


def test_log_metrics_non_string_dimension_values(capsys, metrics, non_str_dimensions, namespace):
# GIVEN Metrics is initialized and dimensions with non-string values are added
my_metrics = Metrics()
my_metrics.add_namespace(**namespace)
for metric in metrics:
my_metrics.add_metric(**metric)
for dimension in non_str_dimensions:
my_metrics.add_dimension(**dimension)

# WHEN we utilize log_metrics to serialize
# and flush all metrics at the end of a function execution
@my_metrics.log_metrics
def lambda_handler(evt, ctx):
return True

lambda_handler({}, {})
output = json.loads(capsys.readouterr().out.strip())

# THEN we should have no exceptions
# and dimension values hould be serialized as strings
for dimension in non_str_dimensions:
assert isinstance(output[dimension["name"]], str)