-
Notifications
You must be signed in to change notification settings - Fork 510
[Metrics] Allow registering one callback for multiple instruments #3667
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Metrics] Allow registering one callback for multiple instruments #3667
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #3667 +/- ##
==========================================
- Coverage 90.16% 89.94% -0.22%
==========================================
Files 223 225 +2
Lines 7172 7273 +101
==========================================
+ Hits 6466 6541 +75
- Misses 706 732 +26
🚀 New features to boost your workflow:
|
67d32ef to
af792aa
Compare
|
Is it possiable to drop |
af792aa to
c182ada
Compare
Is the ask here to essentially do... i.e. to re-implement the existing single-observable callback functionality in terms of the multi-observable callback functionality? Yes, I can do this - let me know if I understood correctly
This I didn't fully understand, because ObservableCallbackRecord and MultiObservableCallbackRecord are implementation details of the SDK ObservableRegistry; users shouldn't be touching these classes, I thought? (In fact: the definition of |
d75abed to
f76d7db
Compare
|
Oh, one more thought; if ObservableRegistry can be thought of as a part of the internal API/ABI of the SDK, I could probably dispense with the ABI version guards in it (since symbols from ObservableRegistry would only be used inside the SDK library itself). this would allow unconditionally reimplementing the existing single-observable callback in terms of the multi-observable implementation. Reckon I should do this? |
|
Yes, it should be safe to do ABI breaking changes with ObservableRegistry. |
Yes, that's what I want.
We maintain cache of registered callbacks in our project, which allow us to do lazy registration, reload , cleanup and some others things, another group of types will make us to double the cache and APIs to maintain them. BTW: It's OK to break ABI or API in v2 now. |
45c9861 to
0abaaf5
Compare
OK, awesome - I think I've done that, hope this looks right to you 🙏 |
6256773 to
3c168b2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds support for registering a single callback function to observe multiple observable instruments, addressing the need to avoid redundant expensive operations when generating multiple related metrics. This implements the multi-instrument callback pattern described in the OpenTelemetry specification.
Key changes include:
- Implementation of
Meter::RegisterCallback()andMeter::DeregisterCallback()methods that work with multiple instruments - New
MultiObserverResultAPI that allows callbacks to record observations for different instruments - Backward-compatible changes that preserve existing single-instrument callback functionality
Reviewed Changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| api/include/opentelemetry/metrics/meter.h | Adds RegisterCallback/DeregisterCallback method signatures for multi-instrument callbacks |
| api/include/opentelemetry/metrics/multi_observer_result.h | New API class defining the interface for recording observations across multiple instruments |
| api/include/opentelemetry/metrics/noop.h | No-op implementation of the new RegisterCallback/DeregisterCallback methods |
| sdk/include/opentelemetry/sdk/metrics/meter.h | SDK implementation declarations for the new callback methods |
| sdk/include/opentelemetry/sdk/metrics/multi_observer_result.h | SDK concrete implementation of MultiObserverResult |
| sdk/include/opentelemetry/sdk/metrics/state/observable_registry.h | Updated registry interface to support multi-instrument callbacks |
| sdk/src/metrics/meter.cc | Implementation of RegisterCallback/DeregisterCallback in the SDK meter |
| sdk/src/metrics/multi_observer_result.cc | Implementation of the MultiObserverResult functionality |
| sdk/src/metrics/state/observable_registry.cc | Refactored registry to handle both single and multi-instrument callback patterns |
| sdk/src/metrics/CMakeLists.txt | Added multi_observer_result.cc to the build |
| sdk/test/metrics/multi_observer_test.cc | Comprehensive tests for the new multi-instrument callback functionality |
| sdk/test/metrics/CMakeLists.txt | Added multi_observer_test to the test suite |
| CHANGELOG.md | Documents the new feature |
Comments suppressed due to low confidence (1)
api/include/opentelemetry/metrics/multi_observer_result.h:1
- Corrected spelling of 'unnescessary' to 'unnecessary'.
// Copyright The OpenTelemetry Authors
marcalff
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great PR, thanks for the contribution.
Please see some questions, approval to follow.
This commit adds a pair of methods `Meter::RegisterCallback` and `Meter::DeregisterCallback` which allow you to set up one callback which can record observations for multiple observable instruments. The callback will be passed an object of type MultiObserverResult, which can be used to get an ObserverResultT for an instrument. This allows a single expensive operation to yield multiple different observable metrics without the need to call said expensive operation multiple times.
e7d7e9d to
ec5fcf2
Compare
|
Thanks, sorry I wasn't able to get to this last week - made the rest of the changes suggested. |
marcalff
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Excellent work. Thank you for the contribution.
|
Thank you, a pleasure working with you. |
Fixes #3653
Changes
This commit adds a pair of methods
Meter::RegisterCallbackandMeter::DeregisterCallbackwhich allow you to set up one callback which can record observations for multiple observable instruments.The callback will be passed an object of type MultiObserverResult, which can be used to get an ObserverResultT for an instrument.
This allows a single expensive operation to yield multiple different observable metrics without the need to call said expensive operation multiple times.
There's a test demonstrating the usage, but the short version is
Design notes
RegisterCallbackbased on the Go SDK, which exposes a RegisterCallback method on the Meter for this purpose. Is this the right name? Is Meter scope the right place to put this?opentelemetry::metrics::ObservableInstrumentpointer somehow throughstatein order to record a measurement. This is in line with the interface sketched out in the spec - https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#multiple-instrument-callbacksObserverResultDirect = std::variant<ObserverResultT<double>, ObserverResultT<int64_t>>when we already haveObserverResult = std::variant<shared_ptr<ObserverResultT<double>>, shared_ptr<ObserverResultT<int64_t>>but it does get rid of a needless extra heap allocation in the multi instrument case so it's probably for the best?MultiObserverResulthas protectedForInstrumentDoubleandForInstrumentInt64; this is needed because you can't have a virtual template method, and I wanted the recording interface to look likeres.ForInstrument<int64_t>(instrument).Observe(value). We could makeForInstrumentreturn a variant, but that would require a) exposingObserverResultDirectas part of the API, and b) requiring the calling code tostd::getorstd::visitthat.ForInstrument. However this seems to be what the spec describes, so I've stuck to the spec.Very keen to hear what you think!
CHANGELOG.mdupdated for non-trivial changes