Skip to content

Commit bc46f91

Browse files
HimtanayaHimtanaya Bhadada
and
Himtanaya Bhadada
authored
Support 30 dimensions per dimension set (#80)
* Support 30 dimensions per dimension set * Bump version to 2.0.0 Co-authored-by: Himtanaya Bhadada <[email protected]>
1 parent e1940a3 commit bc46f91

File tree

7 files changed

+99
-39
lines changed

7 files changed

+99
-39
lines changed

aws_embedded_metrics/constants.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@
1212
# limitations under the License.
1313

1414
DEFAULT_NAMESPACE = "aws-embedded-metrics"
15-
MAX_DIMENSIONS = 9
15+
MAX_DIMENSION_SET_SIZE = 30
1616
MAX_METRICS_PER_EVENT = 100
1717
MAX_DATAPOINTS_PER_METRIC = 100

aws_embedded_metrics/exceptions.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Copyright 2022 Amazon.com, Inc. or its affiliates.
2+
# Licensed under the Apache License, Version 2.0 (the
3+
# "License"); you may not use this file except in compliance
4+
# with the License. You may obtain a copy of the License at
5+
#
6+
# http://www.apache.org/licenses/LICENSE-2.0
7+
#
8+
# Unless required by applicable law or agreed to in writing, software
9+
# distributed under the License is distributed on an "AS IS" BASIS,
10+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
# See the License for the specific language governing permissions and
12+
# limitations under the License.
13+
14+
class DimensionSetExceededError(Exception):
15+
def __init__(self, message: str) -> None:
16+
# Call the base class constructor with the parameters it needs
17+
super().__init__(message)

aws_embedded_metrics/logger/metrics_context.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
from aws_embedded_metrics import constants, utils
1616
from aws_embedded_metrics.config import get_config
17+
from aws_embedded_metrics.constants import MAX_DIMENSION_SET_SIZE
18+
from aws_embedded_metrics.exceptions import DimensionSetExceededError
1719
from aws_embedded_metrics.logger.metric import Metric
1820
from typing import List, Dict, Any
1921

@@ -55,6 +57,15 @@ def put_metric(self, key: str, value: float, unit: str = None) -> None:
5557
else:
5658
self.metrics[key] = Metric(value, unit)
5759

60+
@staticmethod
61+
def validate_dimension_set(dimensions: Dict[str, str]) -> None:
62+
"""
63+
Validates dimension set length is not more than MAX_DIMENSION_SET_SIZE
64+
"""
65+
if len(dimensions) > MAX_DIMENSION_SET_SIZE:
66+
raise DimensionSetExceededError(
67+
f"Maximum number of dimensions per dimension set allowed are {MAX_DIMENSION_SET_SIZE}")
68+
5869
def put_dimensions(self, dimensions: Dict[str, str]) -> None:
5970
"""
6071
Adds dimensions to the context.
@@ -66,6 +77,8 @@ def put_dimensions(self, dimensions: Dict[str, str]) -> None:
6677
# TODO add ability to define failure strategy
6778
return
6879

80+
self.validate_dimension_set(dimensions)
81+
6982
self.dimensions.append(dimensions)
7083

7184
def set_dimensions(self, dimensionSets: List[Dict[str, str]]) -> None:
@@ -78,6 +91,10 @@ def set_dimensions(self, dimensionSets: List[Dict[str, str]]) -> None:
7891
```
7992
"""
8093
self.should_use_default_dimensions = False
94+
95+
for dimensionSet in dimensionSets:
96+
self.validate_dimension_set(dimensionSet)
97+
8198
self.dimensions = dimensionSets
8299

83100
def set_default_dimensions(self, default_dimensions: Dict) -> None:

aws_embedded_metrics/serializers/log_serializer.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@
1515
from aws_embedded_metrics.logger.metrics_context import MetricsContext
1616
from aws_embedded_metrics.serializers import Serializer
1717
from aws_embedded_metrics.constants import (
18-
MAX_DIMENSIONS, MAX_METRICS_PER_EVENT, MAX_DATAPOINTS_PER_METRIC
18+
MAX_DIMENSION_SET_SIZE, MAX_METRICS_PER_EVENT, MAX_DATAPOINTS_PER_METRIC
1919
)
20+
from aws_embedded_metrics.exceptions import DimensionSetExceededError
2021
import json
2122
from typing import Any, Dict, List
2223

@@ -31,7 +32,11 @@ def serialize(context: MetricsContext) -> List[str]:
3132

3233
for dimension_set in context.get_dimensions():
3334
keys = list(dimension_set.keys())
34-
dimension_keys.append(keys[0:MAX_DIMENSIONS])
35+
if len(keys) > MAX_DIMENSION_SET_SIZE:
36+
err_msg = (f"Maximum number of dimensions per dimension set allowed are {MAX_DIMENSION_SET_SIZE}. "
37+
f"Account for default dimensions if not using set_dimensions.")
38+
raise DimensionSetExceededError(err_msg)
39+
dimension_keys.append(keys)
3540
dimensions_properties = {**dimensions_properties, **dimension_set}
3641

3742
def create_body() -> Dict[str, Any]:

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
setup(
77
name="aws-embedded-metrics",
8-
version="1.0.8",
8+
version="2.0.0",
99
author="Amazon Web Services",
1010
author_email="[email protected]",
1111
description="AWS Embedded Metrics Package",

tests/logger/test_metrics_context.py

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
from aws_embedded_metrics import config
22
from aws_embedded_metrics.logger.metrics_context import MetricsContext
33
from aws_embedded_metrics.constants import DEFAULT_NAMESPACE
4+
from aws_embedded_metrics.exceptions import DimensionSetExceededError
45
from importlib import reload
56
from faker import Faker
7+
import pytest
68

79
fake = Faker()
810

@@ -42,14 +44,14 @@ def test_put_dimension_adds_to_dimensions():
4244
# arrange
4345
context = MetricsContext()
4446

45-
dimension_key = fake.word()
46-
dimension_value = fake.word()
47+
dimensions_to_add = 30
48+
dimension_set = generate_dimension_set(dimensions_to_add)
4749

4850
# act
49-
context.put_dimensions({dimension_key: dimension_value})
51+
context.put_dimensions(dimension_set)
5052

5153
# assert
52-
assert context.dimensions == [{dimension_key: dimension_value}]
54+
assert context.dimensions == [dimension_set]
5355

5456

5557
def test_get_dimensions_returns_only_custom_dimensions_if_no_default_dimensions_not_set():
@@ -264,3 +266,32 @@ def test_create_copy_with_context_does_not_repeat_dimensions():
264266

265267
# assert
266268
assert len(new_context.get_dimensions()) == 1
269+
270+
271+
def test_cannot_set_more_than_30_dimensions():
272+
context = MetricsContext()
273+
dimensions_to_add = 32
274+
dimension_set = generate_dimension_set(dimensions_to_add)
275+
276+
with pytest.raises(DimensionSetExceededError):
277+
context.set_dimensions([dimension_set])
278+
279+
280+
def test_cannot_put_more_than_30_dimensions():
281+
context = MetricsContext()
282+
dimensions_to_add = 32
283+
dimension_set = generate_dimension_set(dimensions_to_add)
284+
285+
with pytest.raises(DimensionSetExceededError):
286+
context.put_dimensions(dimension_set)
287+
288+
289+
# Test utility method
290+
291+
292+
def generate_dimension_set(dimensions_to_add):
293+
dimension_set = {}
294+
for i in range(0, dimensions_to_add):
295+
dimension_set[f"{i}"] = fake.word()
296+
297+
return dimension_set

tests/serializer/test_log_serializer.py

Lines changed: 21 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
from aws_embedded_metrics.config import get_config
2+
from aws_embedded_metrics.exceptions import DimensionSetExceededError
23
from aws_embedded_metrics.logger.metrics_context import MetricsContext
34
from aws_embedded_metrics.serializers.log_serializer import LogSerializer
45
from collections import Counter
56
from faker import Faker
67
import json
8+
import pytest
79

810
fake = Faker()
911

@@ -30,37 +32,6 @@ def test_serialize_dimensions():
3032
assert_json_equality(result_json, expected)
3133

3234

33-
def test_cannot_serialize_more_than_9_dimensions():
34-
# arrange
35-
dimensions = {}
36-
dimension_pointers = []
37-
allowed_dimensions = 9
38-
dimensions_to_add = 15
39-
40-
for i in range(0, dimensions_to_add):
41-
print(i)
42-
expected_key = f"{i}"
43-
expected_value = fake.word()
44-
dimensions[expected_key] = expected_value
45-
dimension_pointers.append(expected_key)
46-
47-
expected_dimensions_pointers = dimension_pointers[0:allowed_dimensions]
48-
49-
expected = {**get_empty_payload(), **dimensions}
50-
expected["_aws"]["CloudWatchMetrics"][0]["Dimensions"].append(
51-
expected_dimensions_pointers
52-
)
53-
54-
context = get_context()
55-
context.put_dimensions(dimensions)
56-
57-
# act
58-
result_json = serializer.serialize(context)[0]
59-
60-
# assert
61-
assert_json_equality(result_json, expected)
62-
63-
6435
def test_serialize_properties():
6536
# arrange
6637
expected_key = fake.word()
@@ -79,6 +50,25 @@ def test_serialize_properties():
7950
assert_json_equality(result_json, expected)
8051

8152

53+
def test_default_and_custom_dimensions_combined_limit_exceeded():
54+
# While serializing default dimensions are added to the custom dimension set,
55+
# and the combined size of the dimension set should not be more than 30
56+
dimensions = {}
57+
default_dimension_key = fake.word()
58+
default_dimension_value = fake.word()
59+
custom_dimensions_to_add = 30
60+
61+
for i in range(0, custom_dimensions_to_add):
62+
dimensions[f"{i}"] = fake.word()
63+
64+
context = get_context()
65+
context.set_default_dimensions({default_dimension_key: default_dimension_value})
66+
context.put_dimensions(dimensions)
67+
68+
with pytest.raises(DimensionSetExceededError):
69+
serializer.serialize(context)
70+
71+
8272
def test_serialize_metrics():
8373
# arrange
8474
expected_key = fake.word()

0 commit comments

Comments
 (0)