Spec update for callbacks on ConfigProvider to support runtime changes#4900
Spec update for callbacks on ConfigProvider to support runtime changes#4900jackshirazi wants to merge 5 commits intoopen-telemetry:mainfrom
Conversation
| * API implementations SHOULD document accepted path syntax in language-specific | ||
| docs and include examples such as `.instrumentation/development.general.http` | ||
| and `.instrumentation/development.java.methods`. |
There was a problem hiding this comment.
these could probably be standard across languages
worth noting whether traversing through arrays is supported
There was a problem hiding this comment.
I gave a standard and language specific example, I'm fine with different examples.
I've added a line (just before this) about arrays, thanks!
There was a problem hiding this comment.
oh, I meant about
implementations SHOULD document accepted path syntax
were you thinking that, e.g. java might use .instrumentation/development.general.http path syntax, while another might use something else, e.g. instrumentation/development->general->http?
There was a problem hiding this comment.
yes, okay I see what you meant. I see what you mean the whole thing should be standardized - is it standardized in declarative config across languages? If so then yes, let's specify standard path syntax accordingly
There was a problem hiding this comment.
@open-telemetry/configuration-approvers what do you think? thanks
There was a problem hiding this comment.
I think it would be good to standardize on something like JSONPath:
Or maybe some sort of abbreviated / subset of the syntax which achieves the goal while keeping the implementation burden reasonable.
Co-authored-by: Trask Stalnaker <trask.stalnaker@gmail.com>
Co-authored-by: Trask Stalnaker <trask.stalnaker@gmail.com>
| * `newConfig` MUST be a valid [`ConfigProperties`](#configproperties) instance | ||
| (never null/nil/None). | ||
| * If the watched node is unset or cleared, `newConfig` MUST represent an empty | ||
| mapping node (equivalent to `{}`). |
There was a problem hiding this comment.
Set and empty vs. unset turns out to be semantically meaningful in declarative config:
# this is valid
tracer_provider:
- processors:
simple:
exporter:
console:
---
# this is invalid
tracer_provider:
- processors:
simple:
exporter:
I think we need to find some way signal this difference to watchers.
| operations. | ||
| * Implementations MUST document callback concurrency guarantees. If they do not, | ||
| users MUST assume callbacks may be invoked concurrently. | ||
| * Closing a registration handle MUST unregister the listener. |
There was a problem hiding this comment.
Need to indicate that a callback is required to have a close operation before specifying behavior for a close operation.
|
|
||
| * If callback execution throws an exception, implementations SHOULD isolate the | ||
| failure to that callback and SHOULD continue notifying other callbacks. | ||
| * If a provider does not support change notifications, registration MUST still |
There was a problem hiding this comment.
This is defining the "noop" behavior of this operation. Elsewhere in the spec we have extracted dedicated noop documents (e.g. metrics noop). It may be time to do the same for the declarative config API.
| The `ConfigProvider` MUST provide the following functions: | ||
|
|
||
| * [Get instrumentation config](#get-instrumentation-config) | ||
| * [Add config change listener](#add-config-change-listener) |
There was a problem hiding this comment.
#nit: could change listener be referring to something other than config? If not, consider dropping.
| * [Add config change listener](#add-config-change-listener) | |
| * [Add change listener](#add-config-change-listener) |
|
As declarative config integrates more tightly into the otel java agent, and as we start looking towards dynamic config solutions like #4738, I think a capability to allow instrumentation to respond to changes in config is essential. Based on #4889, only PHP and Java have implemented the ConfigProvider API. So curious if @Nevay / @brettmc have identified any need for this. As for other declarative config implementers, @codeboten, @MikeGoldsmith, @maryliag, @Kielek, @ysolomchenko, @marcalff, even if you haven't implemented ConfigProvider API yet, does this use case listening for config changes resonate with you? |
|
A way to watch a config and automatically reload would be welcome to remove the need to restart a service to pick up new changes. I don't think it would be a hard requirement though. |
|
@jack-berg, the hot reload functionality sounds great, but it should not be marked as required functionality. It should be up to the technology to decide if it can be implemented or no. I suppose that also partial support can be considered with returned information to configuration provide (OpAMP?) that some settings cannot be applied without process restart. |
|
Is there any prototype for this? |
What is more, making (especially everything) "hot reload" will make the SDK less efficient because of required additional synchronization. In my opinion, the prototype should include extensive benchmarks. I am worried that this is going to add more synchronization on the hot path. |
The hot reload proposed here is limited only to ConfigProvider, the API portion of declarative config which instrumentations use for configuration. So its not on the hot path of the internals of the SDK, but the synchornization would still on the hot path for each individual instrumentation. I.e. if an http instrumentation supports dynamic config, it would have to synchronize the logic that determines if / which HTTP request / response headers to capture (amongst other things). This convo reminds me of the convo #4645. I initially pushed back, favoring eventual visibility without guarantees for performance reasons, but was ultimately convinced that an additional .8ns per record operation was low enough overhead to not worry. I believe the same level of synchronization and overhead would occur here as a result of instrumentation config changing.
@jackshirazi has been sketching out the API here. Notably, there is no SDK implementation, nor proposed SDK spec here. I think that needs to change.
Yeah we should talk about this. Besides the potential performance overhead from runtime changes to instrumentation config, there's also the additional complexity required. Even if every language supported the ability to watch for changes, we can't force every instrumentation to call those watch APIs (although we could encourage, similar to how we don't force semantic conventions but encourage). What does it mean for the UX if only some instrumentation is written to be responsive to runtime changes? |
Co-authored-by: Jack Berg <34418638+jack-berg@users.noreply.github.com>
|
Runtime changes are for few and select components. The TelemetryPolicy that this aligns to does not at all expect reload of all components, nor even that they be enabled to do so. The intention is that IF some component is enabled to handle runtime changes, THEN there is a mechanism for it to receive those changes. For Java, there are maybe a dozen components that will be implemented to adapt to runtime configuration changes, and at the moment only one instrumentation that is proposed to adapt to runtime changes. This is very targeted.
|
Fixes #4899
Changes
This PR extends
specification/configuration/api.mdto define a language-neutralConfigProviderchange-listener contract for runtime declarative configuration updates.Spec updates include:
Add config change listeneras a requiredConfigProvideroperationpath+ updatedConfigProperties)newConfigis a valid instance representing an empty mapping node when unset/cleared)CHANGELOG.mdfile updated for non-trivial changes