Skip to content

Bug: metrics.set_default_dimensions emits PowertoolsUserWarning: Dimension 'Key' has already been added. The previous value will be overwritten. #8402

Description

@ericbn

Expected Behaviour

When adding new default dimensions to a Metrics instance using metrics.set_default_dimensions(Key=value) there should be no WARNING logs if they were not set before.

Current Behaviour

When adding new default dimensions to a Metrics instance using metrics.set_default_dimensions(Key=value) there are two WARNING logs being emitted:

[WARNING] aws_lambda_powertools/metrics/metrics.py:124: PowertoolsUserWarning: Dimension 'Key' has already been added. The previous value will be overwritten.
  self.provider.add_dimension(name=name, value=value)

[WARNING] aws_lambda_powertools/metrics/provider/cloudwatch_emf/cloudwatch.py:571: PowertoolsUserWarning: Dimension 'Key' has already been added. The previous value will be overwritten.
  self.add_dimension(name, value)

Code snippet

metrics = Metrics()
    metrics.set_default_dimensions(Environment=os.environ["STAGE"], Resource="MyJob")
    metrics.add_metric(name="MyJobDuration", unit=MetricUnit.Seconds, value=42)
    metrics.flush_metrics()

Possible Solution

def set_default_dimensions(self, **dimensions) -> None:
self.provider.set_default_dimensions(**dimensions)
"""Persist dimensions across Lambda invocations
Parameters
----------
dimensions : dict[str, Any], optional
metric dimensions as key=value
Example
-------
**Sets some default dimensions that will always be present across metrics and invocations**
from aws_lambda_powertools import Metrics
metrics = Metrics(namespace="ServerlessAirline", service="payment")
metrics.set_default_dimensions(environment="demo", another="one")
@metrics.log_metrics()
def lambda_handler():
return True
"""
for name, value in dimensions.items():
self.add_dimension(name, value)
self.default_dimensions.update(**dimensions)

In the Metrics.set_default_dimensions method, these two code snippets seem to be doing duplicated work:

        self.provider.set_default_dimensions(**dimensions)

and

        for name, value in dimensions.items():
            self.add_dimension(name, value)

as both end up calling add_dimension in the provider, which will happen twice. The solution is not totally clear to me as I didn't go deeper into understanding the self.dimension_set, self.default_dimensions, self.provider.dimension_set and self.provided.default_dimensions relationship. Does it make sense to have these structures duplicated in self and self.provider?

Steps to Reproduce

  1. Set the following environment variables in the Lambda function:
    POWERTOOLS_METRICS_NAMESPACE: MyNamespace
    POWERTOOLS_PARAMETERS_MAX_AGE: 900
    POWERTOOLS_PARAMETERS_SSM_DECRYPT: true
    POWERTOOLS_SERVICE_NAME: MyService
    STAGE: dev
    
  2. Add the code snipped to the Lambda function code.
  3. Run the Lambda function.
  4. Observe the logs containing the WARNING entries for the Environment and Resource keys.

Powertools for AWS Lambda (Python) version

3.34.0

AWS Lambda function runtime

3.14

Packaging format used

Lambda Layers

Debugging logs

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingtriagePending triage from maintainers

    Type

    No type

    Projects

    Status
    Triage

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions