-
Notifications
You must be signed in to change notification settings - Fork 649
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
DefaultTracerProvider set permanently in global var, does not look up user-configurable provider #1159
Comments
) Co-authored-by: Daniel Dyla <[email protected]>
Just some background on the reason it works like this. Library authors should instrument their code with the
Definitely it can be tricky. That is the intention behind logging a warning (#781), so that it doesn't fail to collect telemetry silently. It should be possible to call
That is a good point, I'm not too familiar with how this should work. Someone else could speak to this. Also just wanted to say that you don't have to use the globals if you don't want to. You can just pass around the TracerProvider or have it as a constant somewhere. The downside is that any code instrumented to use the global one won't collect telemetry. |
Dup: #1276 |
@owais |
Sure, just wanted to share it as it showed a real world example of where import order is not necessarily in users' control. |
@owais from the other issue, i had a question about the django app:
Any idea why this happens before the setup in wsgi.py? I thought that would be the first thing to run. Would be good to understand the cases where folks are running into this |
We discussed this in SIG and I think we should continue discussion before deciding how to move forward. Some options:
1. is the only way to prevent spans/metrics from being dropped, because it forces the user to be explicit. |
All entrypoints [should] have different names, and user may specify desired one before imports. But it's not possible to decide on components at later steps (e.g. after loading the confutation from external source) |
Continuing the discussion with @anton-ryzhov from #1445 here:
I agree it's not obvious and should be better documented. We want instrumentation to be as easy as possible for users. To me it's not that strange of a requirement for an instrumentation library to do setup at the beginning before other things happen; I would rather folks explicitly set what they want than lose traces/metrics because things ran in an unexpected order or an import took longer than expected. I'm worried the proxy approach might encourage this. Logging is also upcoming in OTel and we don't want to lose startup logs. |
I see a trade off here between:
People may fall on different ends here, and I see a strong emphasize of (1) with the overall project (which makes sense). For adoption of OTel at our company I have to balance this with the developer expectations that instrumentation libraries are safe to use and predictable. For example, we have the following policies, that we enforce in our OTel "distribution" we release for internal use:
From my experience, the developer expectation is that initialization and object creation is started at the main() call and is not a side-effect of the import. I would not expect applications to emit spans before main is called. If spans were to be created before the instrumentation is initialized, I would expect these spans to be dropped. So my current hunch is that we will need to defer initialization in some ways (e.g. via 2) for our internal use. |
Interestingly, while the global tracer handling code was completely rewritten since then, this seems to be the same problem as #45 |
FYI, opentelemetry-js has a I wonder if both Python and JS go ahead with this approach if it should be in the Tracing API spec (which is frozen)? Last SIG, we discussed |
This indeed does what you expect it to do. It takes the first entry from the group matching name but the name is configurable in the user project. If the name is not set it defaults to While this issue is about cc // @aabmass |
@lonewolf3739 is right, I missed these envvars before and it seems like a nice simple solution. @anton-ryzhov @HeinrichHartmann does setting that environment variable work for your use case? The correct SDK provider will be set and you can use |
I doubt if setting a environment variable could be considered as easy-to-use and user-friendly (user=developer that imported this library) solution. For prod, in docker for example, it's fine and usual to pass configs as env. But that's weird requirement for developers env. "If you want to use this lib — add this to your In my opinion it's still better to hardcode (with an explanation and apologizing comment) the value at first line of top And is all that only to select one of only implementation? Could maybe SDK be a default setting if it's installed and use We had a discussion today in other PR about what may surprise users. |
Hold on… I just tried your suggestion. But I may add They only could be set before first import → they can't be dynamically loaded from arbitrary source → they should be hardcoded? |
It is very under-documented, just letting you know that |
So if I need to get these values from some config storage I need to run "pre-executable" process, fetch all these values, populate env and then |
We discussed in the 2021-01-14 SIG meeting and agreed to go with the proxy approach in #1445. It will be a little more complicated for metrics (must have |
@aabmass If I remember correctly, this happens because when we run the service with manage.py, django imports the urls, views, models etc to inspect internally before running the extra code we add. Sorry for being a little late with the reply :D |
Describe your environment
Python3.7 sdk 0.12b0
Steps to reproduce
trace.get_tracer(name)
trace.get_tracer_provider().add_span_processor(OITracing._span_processor)
=> E AttributeError: 'DefaultTracerProvider' object has no attribute 'add_span_processor'
ok, then
trace.set_tracer_provider(
TracerProvider(sampler=trace_api.sampling.ALWAYS_ON))
=> WARNING: opentelemetry.trace:Overriding of current TracerProvider is not allowed
This situation is not correctable
What is the expected behavior?
What is the actual behavior?
it calls get_tracer_provider, which SETS global _TRACER_PROVIDER=DefaultTraceProvider, which cannot be overwritten
Additional context
getter should not set global flag, esp when it is not possible to recover from this and provide the right setting. Order of code initialization can be a tricky issue to resolve, e.g. I have an external package call get_tracer() before I have a chance to initialize things properly
I looked at how _load_provider() works. But it is actually used only to load a default_tracer_provider, which it naturally finds in opentelemetry-sdk. Since it takes the first entry (using next()) on the generator, there is no way to override that either, so what is the point of doing this configuration lookup if you know it will be DefaultTracerPrivider? I thought it will look up 'tracer_provider' that can be configured in user project. Naming the method load_provider() would indicate that https://github.com/open-telemetry/opentelemetry-python/blob/master/opentelemetry-api/src/opentelemetry/util/__init__.py#L51
The text was updated successfully, but these errors were encountered: