Repository navigation
[SDK] Support MeterConfigurator updates and example - #4313
adityabavadekar wants to merge 35 commits into
Conversation
Adds MeterProvider::UpdateMeterConfigurator. It sets a new MeterConfig on all meters that already exist, and new meters get the new configurator too. The update takes the same lock as GetMeter, so GetMeter can never hand back a meter with an old config. The meter enabled flag is now an atomic, so the update does not block instrument creation or Collect.
|
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #4313 +/- ##
==========================================
- Coverage 86.81% 86.63% -0.18%
==========================================
Files 525 526 +1
Lines 20736 20809 +73
==========================================
+ Hits 18000 18025 +25
- Misses 2736 2784 +48
🚀 New features to boost your workflow:
|
Fixes include lists reported by include-what-you-use. Adds a bazel target for the example, and tests for the null configurator and invalid context branches.
eeaf61d to
ab71694
Compare
dbarker
left a comment
There was a problem hiding this comment.
Thanks for the feature and tests! Please see some initial comments below.
| const std::lock_guard<std::mutex> guard(lock_); | ||
| context_->SetMeterConfigurator(std::move(meter_configurator)); | ||
|
|
||
| for (auto &meter : context_->GetMeters()) |
There was a problem hiding this comment.
for (auto &meter : context_->GetMeters())GetMeters() is explicitly non-thread-safe, so this loop is safe only under a cross-class invariant: every production mutation of meters_ currently reaches AddMeter() or RemoveMeter() through a MeterProvider method that holds lock_. That invariant is not stated here, and it is not structurally enforced because MeterContext exposes both mutators publicly.
T1: provider lock_ -> GetMeters() -> iterate borrowed span
T2: meter_lock_ -> AddMeter() -> meters_ may reallocate
lock_ does not exclude a direct/future T2 caller. The analogous tracer and logger loops explicitly document their ownership invariant, and their collections are provider-private.
Please either enforce this invariant by using ForEachMeter() or making the mutators provider-only, or at minimum add the equivalent ownership comment above this loop so future callers do not introduce a race.
There was a problem hiding this comment.
Switched to ForEachMeter
- Share the Meter enabled flag with its instruments so they observe config changes - Drop the creation-time noop branches, so a disabled Meter no longer returns a permanent noop - Remove kNoopMeter, now unused - Keep GetMeters() in UpdateMeterConfigurator; ForEachMeter deadlocks against the collect path - Gate SyncMetricStorage::Bind so a disabled Meter does not consume cardinality - Skip duplicate-instrument warnings while a Meter is disabled - Rename Meter::IsMeterEnabled to IsEnabled - Assert collected sums in tests instead of only scope names - Add regression tests for revival, disable, the deadlock, and Bind cardinality - Use cstdint and std types in the example, and cut its export interval to 10s - Drop the README claim that the export transcript is exact
dbarker
left a comment
There was a problem hiding this comment.
Thanks for the updates! Please see some feedback and requested changes below.
|
Hi @adityabavadekar, Just checking in. Are you still interested in contributing this PR? |
Bind returned nullptr for a disabled meter and the caller wrapped it into a non-null handle with null storage, so the instrument stayed silent even after re-enabling. Handles now bind lazily on the first record. BoundCounterObservesMeterEnabledState missed this by giving the storage and the instrument separate enabled states. Also: - Require meter_enabled_state in SyncMetricStorage, dropping the null checks it makes unreachable in Bind and Synchronous::IsEnabled. - Keep the instrument identity warnings in meter.cc independent of IsEnabled. - Remove UpdateMeterConfiguratorConcurrentWithCollectDoesNotDeadlock, which relied on unsupported reentrant GetMeter and caused the tsan lock-order inversion. - Resolve the reported include-what-you-use diagnostics.
|
Yes, I am still interested, and I have fixed the issues you mentioned. Please review.
|
- Drop the includes iwyu reports as unused in sync_instruments.cc and sync_metric_storage_gauge_test.cc. mutex is kept with an IWYU pragma because LazyBoundEntry uses std::mutex and std::lock_guard directly. - Use cstdint rather than stdint.h in meter_provider_sdk_test.cc.
Co-authored-by: Marc Alff <marc.alff@free.fr>
Co-authored-by: Marc Alff <marc.alff@free.fr>
|
Trying to resolve remaining IWYU issues, but doing that with the web UI with comments ... it may take a few attempts. |
Co-authored-by: Marc Alff <marc.alff@free.fr>
Co-authored-by: Marc Alff <marc.alff@free.fr>
Co-authored-by: Marc Alff <marc.alff@free.fr>
|
Thanks for the contribution. I did small fixes to includes, to make the IWYU CI pass in all 3 flavors, so CI is now clean. Please look again, I think your comments have been addressed. |
|
@dbarker I have fix the GCC build issue and all of the tests are passing now. I've also updated the PR description to match latest changes. Please let me know if anything else is needed before this can be merged. |
Fixes #4256
Adds the ability to update a
MeterConfigurator(and theMeterConfigofexisting meters) at runtime. Following the pattern used in #4065 and #4224.
This implements the optional requirement to allow updating the
MeterProvider's MeterConfigurator:
https://opentelemetry.io/docs/specs/otel/metrics/sdk/#meterconfigurator
Changes
UpdateMeterConfiguratortoMeterProviderto support setting newmeter configs at runtime. The update holds the same lock as
GetMeter, so ameter is never returned with a config that is out of date with the provider
configurator. A null configurator is ignored.
Meterenabled flag into an atomic state shared with itsinstruments, so updates reach existing instruments without blocking
instrument creation or
Collect.MeterContext::SetMeterConfigurator.Behavior
While a Meter is disabled (also covered in the example README):
For significant contributions please make sure you have completed the following items:
CHANGELOG.mdupdated for non-trivial changes