diff --git a/aws_lambda_powertools/metrics/metrics.py b/aws_lambda_powertools/metrics/metrics.py index 2ed7b43c35e..c7a73adc88d 100644 --- a/aws_lambda_powertools/metrics/metrics.py +++ b/aws_lambda_powertools/metrics/metrics.py @@ -174,7 +174,6 @@ def log_metrics( ) def set_default_dimensions(self, **dimensions) -> None: - self.provider.set_default_dimensions(**dimensions) """Persist dimensions across Lambda invocations Parameters @@ -195,9 +194,7 @@ def set_default_dimensions(self, **dimensions) -> None: def lambda_handler(): return True """ - for name, value in dimensions.items(): - self.add_dimension(name, value) - + self.provider.set_default_dimensions(**dimensions) self.default_dimensions.update(**dimensions) def clear_default_dimensions(self) -> None: diff --git a/aws_lambda_powertools/metrics/provider/cloudwatch_emf/cloudwatch.py b/aws_lambda_powertools/metrics/provider/cloudwatch_emf/cloudwatch.py index 243fc561593..267e4308390 100644 --- a/aws_lambda_powertools/metrics/provider/cloudwatch_emf/cloudwatch.py +++ b/aws_lambda_powertools/metrics/provider/cloudwatch_emf/cloudwatch.py @@ -317,7 +317,7 @@ def add_dimension(self, name: str, value: str) -> None: ) return - if name in self.dimension_set or name in self.default_dimensions: + if name in self.dimension_set and self.dimension_set[name] != value: warnings.warn( f"Dimension '{name}' has already been added. The previous value will be overwritten.", category=PowertoolsUserWarning, 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 834575e4754..5c11f205cfa 100644 --- a/tests/functional/metrics/required_dependencies/test_metrics_cloudwatch_emf.py +++ b/tests/functional/metrics/required_dependencies/test_metrics_cloudwatch_emf.py @@ -1133,6 +1133,80 @@ def test_clear_default_dimensions(namespace): assert not my_metrics.default_dimensions +def test_set_default_dimensions_no_warning_on_first_call(namespace): + # GIVEN a Metrics instance with no dimensions set + my_metrics = Metrics(namespace=namespace) + + # WHEN we persist default dimensions for the first time + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter("default") + my_metrics.set_default_dimensions(environment="test", log_group="/lambda/test") + + # THEN no overwrite warning should be emitted + assert not [warning for warning in w if "has already been added" in str(warning.message)] + + +def test_set_default_dimensions_no_warning_when_unchanged(namespace): + # GIVEN a Metrics instance with default dimensions persisted + my_metrics = Metrics(namespace=namespace) + my_metrics.set_default_dimensions(environment="test", log_group="/lambda/test") + + # WHEN we persist the same default dimensions again e.g., on a warm invocation + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter("default") + my_metrics.set_default_dimensions(environment="test", log_group="/lambda/test") + + # THEN no overwrite warning should be emitted + assert not [warning for warning in w if "has already been added" in str(warning.message)] + + +def test_set_default_dimensions_warns_when_value_changes(namespace): + # GIVEN a Metrics instance with a default dimension persisted + my_metrics = Metrics(namespace=namespace) + my_metrics.set_default_dimensions(environment="test") + + # WHEN we persist the same default dimension with a different value + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter("default") + my_metrics.set_default_dimensions(environment="prod") + + # THEN a single overwrite warning should be emitted + assert len([warning for warning in w if "has already been added" in str(warning.message)]) == 1 + + +def test_log_metrics_with_default_dimensions_no_warning_across_invocations(namespace, metric, capsys): + # GIVEN a Metrics instance with default dimensions persisted + my_metrics = Metrics(namespace=namespace) + my_metrics.set_default_dimensions(environment="test", log_group="/lambda/test") + + @my_metrics.log_metrics + def lambda_handler(evt, ctx): + my_metrics.add_metric(**metric) + + # WHEN metrics are flushed across multiple invocations + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter("default") + lambda_handler({}, {}) + lambda_handler({}, {}) + + # THEN no overwrite warning should be emitted + assert not [warning for warning in w if "has already been added" in str(warning.message)] + + +def test_add_dimension_no_warning_when_value_unchanged(namespace): + # GIVEN a Metrics instance with a dimension added + my_metrics = Metrics(namespace=namespace) + my_metrics.add_dimension("environment", "test") + + # WHEN the same dimension is added again with the same value + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter("default") + my_metrics.add_dimension("environment", "test") + + # THEN no overwrite warning should be emitted + assert not [warning for warning in w if "has already been added" in str(warning.message)] + + def test_add_dimensions_with_empty_value(namespace, capsys, metric): # GIVEN Metrics is initialized my_metrics = Metrics(namespace=namespace)