Skip to content

sdk/metrics: copy attributes dict to prevent post-recording mutation#5106

Merged
xrmx merged 9 commits into
open-telemetry:mainfrom
tejas-ae:fix/metrics-attributes-copy
May 15, 2026
Merged

sdk/metrics: copy attributes dict to prevent post-recording mutation#5106
xrmx merged 9 commits into
open-telemetry:mainfrom
tejas-ae:fix/metrics-attributes-copy

Conversation

@tejas-ae

@tejas-ae tejas-ae commented Apr 15, 2026

Copy link
Copy Markdown
Contributor

Description

When a caller retains a reference to the attributes dict passed to counter.add() (or any instrument's add/record call) and mutates it after the call, the mutation silently corrupts the attributes stored on the aggregation and therefore on exported data points.

The root cause is in _ViewInstrumentMatch.consume_measurement: when no attribute key filter is active, the code assigned the measurement's attributes dict directly:

# before
attributes = measurement.attributes

That dict is then passed to _create_aggregation, which stores it as self._attributes in the _Aggregation base class. Any subsequent mutation of the caller's dict changes what gets exported.

The fix is a one-line copy:

# after
attributes = dict(measurement.attributes)

A shallow copy is enough for all attribute value types (str, bool, int, float, and their sequence variants) because those values are themselves immutable once stored.

The filtered path (when _view._attribute_keys is not None) already builds a fresh dict via comprehension, so it is unaffected.

Fixes #4610

Type of change

  • Bug fix (non-breaking change which fixes an issue)

How Has This Been Tested?

A regression test is included that records a measurement, mutates the original dict, and verifies the exported data point still carries the original attributes.

  • Unit test added in opentelemetry-sdk/tests/metrics/

Does This PR Require a Contrib Repo Change?

  • No.

Checklist:

  • Followed the style guidelines of this project
  • Changelogs have been updated
  • Unit tests have been added
  • Documentation has been updated

@tejas-ae
tejas-ae requested a review from a team as a code owner April 15, 2026 12:50
@linux-foundation-easycla

linux-foundation-easycla Bot commented Apr 15, 2026

Copy link
Copy Markdown

CLA Signed

The committers listed above are authorized under a signed CLA.

  • ✅ login: MikeGoldsmith / name: Mike Goldsmith (899d92b)
  • ✅ login: tejasae-afk / name: Tejas (24b14a6)
  • ✅ login: tejasae-afk / name: tejasae-afk (e720812)

@tammy-baylis-swi

Copy link
Copy Markdown
Contributor

THanks for this! Please sign the CLA.

@MikeGoldsmith MikeGoldsmith left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes look good. I've left one suggestion to fix the changelog.

Also, please could you update the PR description to follow the PR template in .github/pull_request_template.md. It helps make sure all relevant details are included and makes reviewing PRs easier / most consistent.

Comment thread CHANGELOG.md Outdated
@tammy-baylis-swi tammy-baylis-swi moved this to Reviewed PRs that need fixes in Python PR digest Apr 18, 2026
@MikeGoldsmith

Copy link
Copy Markdown
Member

@tejasae-afk EasyCLA can't verify ClaudeCode as a co-author on this commit (08c2390). You'll need to update it.

@github-actions

github-actions Bot commented May 6, 2026

Copy link
Copy Markdown

This PR has been automatically marked as stale because it has not had any activity for 14 days. It will be closed if no further activity occurs within 14 days of this comment.
If you're still working on this, please add a comment or push new commits.

@github-actions github-actions Bot added the Stale label May 6, 2026
@MikeGoldsmith

Copy link
Copy Markdown
Member

@tejasae-afk we cannot accept contributions unless you sign the CLA, please sign it.

@github-actions github-actions Bot removed the Stale label May 8, 2026
@tejas-ae
tejas-ae force-pushed the fix/metrics-attributes-copy branch from 08c2390 to dea8513 Compare May 9, 2026 03:38
@tejas-ae

tejas-ae commented May 9, 2026

Copy link
Copy Markdown
Contributor Author

/easycla

tejasae-afk added 2 commits May 8, 2026 23:41
…utation

When a caller retains a reference to the attributes dict passed to
counter.add() (or any instrument record/add call), mutating that dict
after the call would silently corrupt the attributes stored on the
aggregation and subsequently on exported data points.

The fix copies the dict at the point where it is first stored as the
canonical attributes for a new aggregation bucket, so downstream
mutations by the caller have no effect.

Fixes open-telemetry#4610
@tejas-ae
tejas-ae force-pushed the fix/metrics-attributes-copy branch from dea8513 to 24b14a6 Compare May 9, 2026 03:41
@MikeGoldsmith MikeGoldsmith moved this from Reviewed PRs that need fixes to Approved PRs in Python PR digest May 11, 2026
@emdneto

emdneto commented May 12, 2026

Copy link
Copy Markdown
Member

Thanks for the PR!

Just a heads-up: we no longer update CHANGELOG.md directly. The changelog is now generated from changelog fragments using Towncrier.

Please add the appropriate changelog fragment for this change instead of editing CHANGELOG.md manually. You can find the instructions and expected format in CONTRIBUTING.md.

Comment thread CHANGELOG.md Outdated
@xrmx xrmx moved this from Approved PRs to Ready for merge in Python PR digest May 15, 2026
Comment thread opentelemetry-sdk/tests/metrics/test_view_instrument_match.py Outdated
@xrmx
xrmx enabled auto-merge (squash) May 15, 2026 14:07
@xrmx
xrmx merged commit 1d69bd2 into open-telemetry:main May 15, 2026
479 checks passed
@github-project-automation github-project-automation Bot moved this from Ready for merge to Done in Python PR digest May 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Counter measurement attributes aren't immutable

5 participants