This is similar to #428 but is more general and applies to the full API. We need to decide what the API behavior should be if API methods are called and no SDK has been registered.
Current behavior as I understand it. If you see a mistake or want me to update this with another language's behavior make a comment.
API | JS | Go | Python | Java | Erlang/Elixir
-|-|-|-|-|-
Context | no-op | n/a | thread local? | gRPC | no-op
Propagation | no-op | no-op | trace/correlation composite | trace context | no-op
Trace | no-op | no-op | no-op | propagation only | no-op
Metrics | no-op | no-op | no-op | no-op | no-op
It looks like Java has the most "complete" implementations in the API with no SDK. It seems like by default if you use the trace API to accept an incoming request, extract headers, start a span, ... make an out going request, it will propagate the same span context that came in on the way out.
Python is the second most complete. The tracer methods don't propagate context, but if you manually manage context, you can propagate traces.
Go and JS both have true no-op implementations of the API. If no SDK is registered, nothing happens when any methods are called. Context management is n/a because context is managed manually in Go.
The Context itself (API+impl) is supposed to be a layer below the OTel API, so I'd say the Java/Go approach is correct here.
I also wouldn't put Go as n/a. It uses context.Context AFAIK.
This is only meant to refer to setting/retrieving active context. Because go manages context manually, there is no possibility that it wouldn't work because there exist no context.active() calls to no-op.
Erlang/Elixir is all no-ops without the SDK.
A pair of things:
1) Python uses contextvars, which work with both threads and coroutines.
2) Java historically intended to do full propagation without a SDK (relying on TraceContext for this).
From the original OTEP, we always had in mind to have a working, canonical implementation of the default context propagation:
The Observability systems ships with a no-op implementation and a pluggable SDK,
the context propagation system ships with a canonical, working implementation.
This is also mentioned at the moment in the Specification:
If offered, the global Propagators should default to a composite Propagator containing W3C Trace Context and Correlation Context Propagators, in order to provide propagation even in the presence of no-op OpenTelemetry implementations.
... which, I think, it's great trade off.
That being said, it feels like we should discuss it in great length in the next SIG call (we were too busy to remember about this one today ;( )
In my opinion it is very confusing that some of the API is no-op without an SDK and some is not. If you want a proxy service that doesn't generate spans, which is a special use-case and not at all the most common, it would be trivial to do this using the SDK.
In my opinion it is very confusing that some of the API is no-op without an SDK and some is not.
The justification is that Context is not the "OTel API." It's part of "data transport" not "observability". https://github.com/open-telemetry/oteps/blob/master/text/0066-separate-context-propagation.md It has been proposed that context be separated from OTel altogether, but for practical reasons, OTel winds up dealing with it.
Configuring the context layer is a language/platform specific concern. It may or may not require configuration.
In Java, there is no configuration required.
In Go, there isn't implicit context and so no configuration is required.
In JavaScript, the context implementation depends on the platform, e.g. Node.js async_hooks must be enabled using asyncHook.enable(). Without shipping an implementation for every platform in @opentelemetry/api, JS has no choice but to choose a no-op default. (And failing to configure context could reasonably break some lib that depended on it. Failing to configure observability could never break a library.)
Erlang/Elixir is no longer a no-op for context https://github.com/open-telemetry/opentelemetry-erlang-api/pull/66
To have a focus discussion, let's make sure we don't duplicate this. I will close this in favor of https://github.com/open-telemetry/opentelemetry-specification/issues/689
Most helpful comment
This is only meant to refer to setting/retrieving active context. Because go manages context manually, there is no possibility that it wouldn't work because there exist no
context.active()calls to no-op.