Skip to content

Commit

Permalink
add function to strip nonascii and stringify numbers (#84)
Browse files Browse the repository at this point in the history
* Add function to strip non-ascii characters and stringify numbers

Co-authored-by: Mark Kuhn <[email protected]>
  • Loading branch information
markkuhn and Mark Kuhn authored Aug 15, 2022
1 parent bc46f91 commit 47bf736
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 10 deletions.
20 changes: 10 additions & 10 deletions aws_embedded_metrics/logger/metrics_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,30 +58,30 @@ def put_metric(self, key: str, value: float, unit: str = None) -> None:
self.metrics[key] = Metric(value, unit)

@staticmethod
def validate_dimension_set(dimensions: Dict[str, str]) -> None:
def validate_dimension_set(dimension_set: Dict[str, str]) -> None:
"""
Validates dimension set length is not more than MAX_DIMENSION_SET_SIZE
"""
if len(dimensions) > MAX_DIMENSION_SET_SIZE:
if len(dimension_set) > MAX_DIMENSION_SET_SIZE:
raise DimensionSetExceededError(
f"Maximum number of dimensions per dimension set allowed are {MAX_DIMENSION_SET_SIZE}")

def put_dimensions(self, dimensions: Dict[str, str]) -> None:
def put_dimensions(self, dimension_set: Dict[str, str]) -> None:
"""
Adds dimensions to the context.
```
context.put_dimensions({ "k1": "v1", "k2": "v2" })
```
"""
if dimensions is None:
if dimension_set is None:
# TODO add ability to define failure strategy
return

self.validate_dimension_set(dimensions)
self.validate_dimension_set(dimension_set)

self.dimensions.append(dimensions)
self.dimensions.append(dimension_set)

def set_dimensions(self, dimensionSets: List[Dict[str, str]]) -> None:
def set_dimensions(self, dimension_sets: List[Dict[str, str]]) -> None:
"""
Overwrite all dimensions.
```
Expand All @@ -92,10 +92,10 @@ def set_dimensions(self, dimensionSets: List[Dict[str, str]]) -> None:
"""
self.should_use_default_dimensions = False

for dimensionSet in dimensionSets:
self.validate_dimension_set(dimensionSet)
for dimension_set in dimension_sets:
self.validate_dimension_set(dimension_set)

self.dimensions = dimensionSets
self.dimensions = dimension_sets

def set_default_dimensions(self, default_dimensions: Dict) -> None:
"""
Expand Down
4 changes: 4 additions & 0 deletions aws_embedded_metrics/serializers/log_serializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ def serialize(context: MetricsContext) -> List[str]:
dimensions_properties: Dict[str, str] = {}

for dimension_set in context.get_dimensions():

# Stringify numerical values and strip non-ascii characters from dimension set values
dimension_set = {k: str(v).encode('ascii', 'ignore').decode('ascii') for k, v in dimension_set.items()}

keys = list(dimension_set.keys())
if len(keys) > MAX_DIMENSION_SET_SIZE:
err_msg = (f"Maximum number of dimensions per dimension set allowed are {MAX_DIMENSION_SET_SIZE}. "
Expand Down
50 changes: 50 additions & 0 deletions tests/serializer/test_log_serializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,56 @@ def test_serialize_dimensions():
assert_json_equality(result_json, expected)


def test_serialize_dimensions_with_numeric_value():
# arrange
expected_key = fake.word()
value = fake.random.randrange(0, 100)
expected_value = str(value)

dimension = {}
dimension[expected_key] = value

expected_dimension = {}
expected_dimension[expected_key] = expected_value

expected = {**get_empty_payload(), **expected_dimension}
expected["_aws"]["CloudWatchMetrics"][0]["Dimensions"].append([expected_key])

context = get_context()
context.put_dimensions(dimension)

# act
result_json = serializer.serialize(context)[0]

# assert
assert_json_equality(result_json, expected)


def test_serialize_dimenions_with_non_ascii_values():
# arrange
expected_key = fake.word()
value = "asciié🤔"
expected_value = "ascii"

dimension = {}
dimension[expected_key] = value

expected_dimension = {}
expected_dimension[expected_key] = expected_value

expected = {**get_empty_payload(), **expected_dimension}
expected["_aws"]["CloudWatchMetrics"][0]["Dimensions"].append([expected_key])

context = get_context()
context.put_dimensions(dimension)

# act
result_json = serializer.serialize(context)[0]

# assert
assert_json_equality(result_json, expected)


def test_serialize_properties():
# arrange
expected_key = fake.word()
Expand Down

0 comments on commit 47bf736

Please sign in to comment.