diff --git a/aws_lambda_powertools/metrics/provider/cloudwatch_emf/cloudwatch.py b/aws_lambda_powertools/metrics/provider/cloudwatch_emf/cloudwatch.py index 5da02528aab..4fc77b9467c 100644 --- a/aws_lambda_powertools/metrics/provider/cloudwatch_emf/cloudwatch.py +++ b/aws_lambda_powertools/metrics/provider/cloudwatch_emf/cloudwatch.py @@ -272,10 +272,20 @@ def add_dimension(self, name: str, value: str) -> None: raise SchemaValidationError( f"Maximum number of dimensions exceeded ({MAX_DIMENSIONS}): Unable to add dimension {name}.", ) - # 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 - self.dimension_set[name] = value if isinstance(value, str) else str(value) + + value = value if isinstance(value, str) else str(value) + + if not name.strip() or not value.strip(): + warnings.warn( + f"The dimension {name} doesn't meet the requirements and won't be added. " + "Ensure the dimension name and value are non empty strings", + stacklevel=2, + ) + else: + # 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 + self.dimension_set[name] = value def add_metadata(self, key: str, value: Any) -> None: """Adds high cardinal metadata for metrics object diff --git a/docs/core/metrics.md b/docs/core/metrics.md index 5f2fec3d134..6fdcf1fa043 100644 --- a/docs/core/metrics.md +++ b/docs/core/metrics.md @@ -25,7 +25,7 @@ If you're new to Amazon CloudWatch, there are five terminologies you must be awa * **Resolution**. It's a value representing the storage resolution for the corresponding metric. Metrics can be either Standard or High resolution. Read more [here](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/publishingMetrics.html#high-resolution-metrics){target="_blank"}.
- + Terminology
Metric terminology, visually explained
@@ -131,6 +131,8 @@ If you'd like to remove them at some point, you can use `clear_default_dimension --8<-- "examples/metrics/src/set_default_dimensions_log_metrics.py" ``` +**Note:** Dimensions with empty values will not be included. + ### Changing default timestamp When creating metrics, we use the current timestamp. If you want to change the timestamp of all the metrics you create, utilize the `set_timestamp` function. You can specify a datetime object or an integer representing an epoch timestamp in milliseconds. diff --git a/tests/functional/metrics/required_dependencies/test_metrics_cloudwatch_emf.py b/tests/functional/metrics/required_dependencies/test_metrics_cloudwatch_emf.py index c09660b4f9a..5633d573a54 100644 --- a/tests/functional/metrics/required_dependencies/test_metrics_cloudwatch_emf.py +++ b/tests/functional/metrics/required_dependencies/test_metrics_cloudwatch_emf.py @@ -1045,6 +1045,25 @@ def test_clear_default_dimensions(namespace): assert not my_metrics.default_dimensions +def test_add_dimensions_with_empty_value(namespace, capsys, metric): + # GIVEN Metrics is initialized + my_metrics = Metrics(namespace=namespace) + + my_dimension = "my_empty_dimension" + + # WHEN we try to add a dimension with empty value + with pytest.warns(UserWarning, match=f"The dimension {my_dimension} doesn't meet the requirements *"): + my_metrics.add_dimension(name="my_empty_dimension", value=" ") + + my_metrics.add_metric(**metric) + my_metrics.flush_metrics() + + output = capture_metrics_output(capsys) + + # THEN the serialized metric should not contain this dimension + assert my_dimension not in output + + def test_get_and_set_namespace_and_service_properties(namespace, service, metrics, capsys): # GIVEN Metrics instance is initialized without namespace and service my_metrics = Metrics()