fix(metrics): warnings when there are default_dimensions - #8404
Conversation
This fixes and reorganizes the code in a few ways:
* Make it clearer that _metrics, _dimensions, _metadata and
_default_dimensions are class attributes. They don't need to be also
set as instance attributes when constructing Metrics, as they're only
meant to be used to construct the provider with shared data.
* Expose metric_set, dimension_set, metadata_set and default_dimensions
as attributes just to keep backwards compatibility. Don't expose setters
for these as previously setting them would have no side effect. Now
users will get an error, which is a small breaking change but arguably
for something they should never be doing anyway.
* Fix setting the default_dimensions in AmazonCloudWatchEMFProvider, as
`default_dimensions or {}` was setting a new dict instance when the
given default_dimensions was empty and we want to share the given dict.
|
Disclaimer: the code changes and description here were not produced using any AI. |
|
Nice catch on I did find two behavior gaps while testing this branch though.
def handler():
metrics = Metrics(namespace="MyNamespace", service="MyService")
metrics.set_default_dimensions(Environment="dev", Resource="MyJob")
metrics.add_metric(name="MyJobDuration", unit=MetricUnit.Seconds, value=42)
metrics.flush_metrics()
On the read-only properties: agreed nobody should be assigning those, but it is still a breaking change on a public attribute, and this file's own maintenance note says breaking customers before v3 is off the table, so that part is probably a maintainer call. |
|
Thanks for testing this so thoroughly. On both points you raised, I checked them against the code as it stood before this PR (commit 1. Repeat invocation warnings — before this PR, the same repeated-invocation scenario from #8402 produced 4 warnings on the very first invocation (from the double 2. Type reverts to non-str — same story. 3. Read-only properties — agreed this is ultimately a maintainer call under the pre-v3 policy. Worth noting the previous behavior wasn't a clean no-op either: reassigning Given all three points trace back to pre-existing behavior rather than regressions introduced here, I'd like to keep this PR as-is and track the two remaining gaps as follow-ups. |
|
On the str cast I have to push back, because I tested this on develop (8db13c7) before commenting. With |
|
@vishwakt our AIs are discussing here over a PR and corresponding issue that were not even triaged by the project maintainers yet. Please I want to wait for the project maintainers feedback first before proceeding further with any other conversation. |
* Property cast dimension value to str in all code that updates dimension_set. * No need to check if `isinstance(value, str)` before casting to str. This is already optimized in CPython, which reuses the same instance if value is already an str. This is unnecessary overengineering.
0def6bd to
11ca80a
Compare
| return self.provider.default_dimensions | ||
|
|
||
|
|
||
| # Maintenance: until v3, we can't afford to break customers. |
There was a problem hiding this comment.
This comment seems outdated, as we're already on v3.
|
There was a problem hiding this comment.
Hi Eric, thank you for taking the time to investigate this and for going deeper into the state-sharing problem. Your finding around default_dimensions or {} is important, and I have asked for that fix to be incorporated into #8403, with credit to you.
After comparing both approaches, I am leaning towards continuing with #8403 for the specific bug reported in #8402. It keeps the change focused and also avoids warnings when the same default dimensions are registered again during warm invocations. In this PR, that scenario can still warn because the existing dimension is treated as an overwrite even when its value has not changed.
The read-only properties are the one part that makes me hesitant. Even if assigning to those attributes was not very useful before, changing them to raise an error could still affect someone. I think we should look at that separately.
Would you be comfortable with us continuing with #8403 for #8402 and handling the broader cleanup separately? I do not want to close this PR before hearing your thoughts.
Thank you again for the investigation and especially for catching the empty dictionary issue.
|
Oi @leandrodamascena! Thanks and I agree there's too much going on in this PR. Also agree replacing the direct references to the shared data by read-only attributes is not worth it -- there are other ways to break these references. Let me revert that, but also break this PR into the smaller different changes, if you agree. I'll list them below so we can discuss first. Regarding #8403, and since I was the (apparently first) one complaining about the warnings in #8402, I insist I don't think it's a good ideia to start hiding the warnings when the key is being set twice but with the same value. The warnings are currently alerting to places where potentially code is being called twice and thanks to them I was able to dig deeper into issues that currently exist. Hiding these warnings when the value is the same will hide other of these potential issues. The test there should be changed, yes, but just to And here's the break down of the different changes I'm proposing:
Item 3 and 4 are what fixes #8402. |
The provider replaced a falsy default_dimensions argument with a new dict, so the initially empty dict that Metrics shares was silently swapped out and updates made through the provider never reached the dict Metrics owns. Keep the given dict unless None is passed. Fix taken from aws-powertools#8404, requested in review. Co-authored-by: Eric Nielsen <4120606+ericbn@users.noreply.github.com>



Issue number: closes #8402
Summary
Changes
This fixes and reorganizes the code in a few ways:
default_dimensions or {}was setting a new dict instance when the given default_dimensions was empty and we want to share the given dict.isinstance(value, str)before casting to str. This is already optimized in CPython, which reuses the same instance if value is already an str. This is unnecessary overengineering.User experience
This fix will not produce the following warnings anymore as it makes sure default dimensions are only set once when using metrics.add_metric and metrics.flush_metrics methods.
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.
Disclaimer: We value your time and bandwidth. As such, any pull requests created on non-triaged issues might not be successful.