Skip to content

fix(sdk): wire MeterProvider in add_metric_reader and allocate reader component ID once - #5897

Open
hardikkaurani wants to merge 2 commits into
open-telemetry:mainfrom
hardikkaurani:fix/metric-reader-provider-wiring-component-id
Open

hardikkaurani wants to merge 2 commits into
open-telemetry:mainfrom
hardikkaurani:fix/metric-reader-provider-wiring-component-id

Conversation

@hardikkaurani

@hardikkaurani hardikkaurani commented Nov 7, 2026 •

Copy link
Copy Markdown

Description

Fixes defects 1 and 2 of #5890. (Note: defect 3 is excluded as it is actively being addressed in open PR #5778).

  1. MeterProvider.add_metric_reader() now calls metric_reader._set_meter_provider(self):
    Previously, add_metric_reader() called metric_reader._set_collect_callback(...) but never called metric_reader._set_meter_provider(self), leaving metric_reader._metrics bound to NoOpMeterProvider() and failing to produce reader collection duration self-observability metrics (otel.sdk.metric_reader.collection.duration).

  2. Allocates MetricReader component ID once per instance:
    Previously, MetricReader.__init__ called create_metric_reader_metrics(..., NoOpMeterProvider(), ...), which prematurely incremented _component_counter[component_type] from 0 to 1 with a no-op provider. When MeterProvider subsequently called metric_reader._set_meter_provider(self), create_metric_reader_metrics was called a second time, incrementing the counter to 2 and naming the first instance <type>/1.
    Now, MetricReader.__init__ initializes self._metrics as NoOpMetricReaderMetrics(), create_metric_reader_metrics returns NoOpMetricReaderMetrics() when passed a NoOpMeterProvider, and MetricReader allocates and stores self._otel_component_id once upon registration (<type>/0 for the first instance).

Related Issues

Type of Change

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

@hardikkaurani
hardikkaurani requested a review from a team as a code owner November 7, 2026 16:29
Copilot AI balanced review requested due to automatic review settings November 7, 2026 16:29

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota. Try requesting a review at a lower effort level.

@opentelemetry-pr-dashboard

opentelemetry-pr-dashboard Bot commented Nov 7, 2026 •

Copy link
Copy Markdown

Pull request dashboard status

Waiting on reviewers · refreshed 2026-11-08 04:00 UTC

Review the latest changes.

Status above doesn't look right?
  • Just replied or pushed? Anything around or after the refresh time above may not be picked up yet — give it a few minutes.
  • Anything look wrong? Report it with what you expected; it helps us improve the dashboard.

@hardikkaurani

Copy link
Copy Markdown
Author

Hi @herin049, could you please take a look at this PR when you have some time?

This addresses defects 1 and 2 from #5890:

  • Calls metric_reader._set_meter_provider(self) in MeterProvider.add_metric_reader(), ensuring readers registered dynamically have their self-observability collection duration metrics wired to the active provider.
  • Allocates MetricReader component ID once per instance by returning NoOpMetricReaderMetrics when initialized with NoOpMeterProvider, preventing premature double-increments of _component_counter and correctly indexing the first instance as <type>/0.

(Note: defect 3 regarding error.type was excluded here as it is actively being addressed in open PR #5778).

Regression tests (with proper cleanup isolation) and Towncrier changelog fragment are included, and EasyCLA is signed.

Thanks!

@knowprasad

Copy link
Copy Markdown
Contributor

Took a look through the changes in opentelemetry-sdk.

Calling metric_reader._set_meter_provider(self) directly in MeterProvider.add_metric_reader() makes sense and brings dynamically added readers to parity with readers supplied at provider initialization.

Initializing self._metrics as NoOpMetricReaderMetrics() and having create_metric_reader_metrics return early when passed NoOpMeterProvider cleanly avoids the double-increment bug on _component_counter. Allocating self._otel_component_id once and reusing it across re-bindings keeps the naming predictable (/0 for the first instance).

The regression tests in est_in_memory_metric_reader.py and est_periodic_exporting_metric_reader.py verify both the initial state and dynamic registration cleanly, and using self.addCleanup for reader and provider shutdowns ensures tests stay properly isolated.

Looks solid to me!

@hardikkaurani

Copy link
Copy Markdown
Author

Thanks for taking the time to go through this and for the detailed feedback!

Glad the approach and the tests look good. I wanted to make sure dynamically added readers behave consistently with readers passed during provider initialization, without introducing any extra component ID increments.

Appreciate you taking a look! @knowprasad

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

3 participants