-
Notifications
You must be signed in to change notification settings - Fork 888
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
Global MeterProvider Get/Set API is under-defined #3068
Comments
This is not generally possible, as you also need to consider the API-only case. E.g. a common use case (although discouraged in some languages) might be to call the global getter somewhere deep in a library that has built-in instrumentation. That library would depend on the API package but not any SDK. Thus, there is no code that could interpret environment variables. .NET, BTW, can probably be left out of this discussion, it is not really "OpenTelemetry" in this regard. |
FWIW I think adding delegation is something that can be done in a non-breaking way. The JS TracerProvider does delegate and it is a feature that I am hoping to add to metrics as well. I would argue the "correct" behavior is a delegating no-op. As far as multi-set, I think that gets much trickier. I prefer the logged warning (no strong opinion on warn/error level). |
This makes sense. 👍 I think to your's and @dyladan point, we should recommend all return a delegating No-op implementation when a get is made before a set, but add a provisional option for an environment based provider for those able to do so. I think the option here is necessary to not make the Java implementation doesn't become incompatible, right? |
Please definitely discuss that with the Java maintainers @open-telemetry/java-maintainers, I think it is a bit more intricate there, autoconfiguration is a third package that is separate from the SDK and not automatically used unless you use the auto-instrumenting agent (which I believe is probably the most common way of "using" the Java language client) |
Hi - let me shed some light on the java behavior:
I think we've arrived at a good place for java: The invariant that all calls to |
Here is a historical reference on this topic, which indicates that Go was influenced by Ruby: open-telemetry/oteps#11 My recollection of the discussion and debate from then is that it matters whether the language in question has a "proper" and well-adopted mechanism for dependency injection and (possibly equivalently) dynamic loading of code. Golang stands out as a language without either of these features, and this is why (IMO) the "delegating no-op" should be supported in Golang. A language with rules and accepted DI mechanism makes the delegating no-op mechanism unnecessary (IMO) because the DI mechanism is a manner of delegation. I don't have a strong opinion about the "multi-set" behavior that is best. IIRC it was Ruby that led the way here, so I'd like to ask @mwear what he thinks? |
So no changes to the spec make us no longer compliant I can describe the Erlang Provider get/set setup: Providers are registered in a central place by utilizing Erlang's process registry. Each Provider is a process that implements a particular (TracerProvider or MeterProvider) API. On startup of the SDK it will configure the global provider which is registered in the process registry. A noop tracer/meter is returned if the global provider is called before it has initialized. Attempts to start another provider registered to the same name will fail, returning We don't actually have functions for set/register because it relies on the Erlang process registry and is best left to the process itself. Long story short, we'd want/need the spec to not require that multiple attempts to set/register the global Provider override the existing Provider. |
|
Why not a delegating provider? |
That's what I meant 😄 Sorry for lack of precision. (edited my comment) |
Currently the specification defines this API as follows:
This does not specify the API behavior when an "access" is made prior to a global being set. Nor does it specify the behavior of multiple set operations. This seems like a source of user confusion if implementations deviate in behavior.
If one implementation errors, another returns a no-op, and another returns a no-op implementation that will be updated to the first global
MeterProvider
set by a user, users that work across these implementations will not know what to expect.Ideally implementations will behave the same. Unfortunately, that doesn't seem possible given the stable releases of certain implementations that have different behaviors.
Based on this survey, I'm not entirely sure how to proceed.
Should we recommend all return from the environment if configured otherwise a delegating No-op implementation when a get is made before a set?
Should all multi-sets log some warning/error?
cc @open-telemetry/go-approvers @open-telemetry/java-approvers @open-telemetry/dotnet-approvers @open-telemetry/python-approvers @open-telemetry/javascript-approvers @open-telemetry/erlang-approvers @open-telemetry/ruby-approvers
The text was updated successfully, but these errors were encountered: