Skip to content

fix: warn when bootstrap loses the set_tracer_provider race - #264

Merged
lesnik512 merged 1 commit into
mainfrom
fix/227-warn-on-lost-tracer-provider
Sep 27, 2026
Merged

lesnik512 merged 1 commit into
mainfrom
fix/227-warn-on-lost-tracer-provider

Conversation

@lesnik512

@lesnik512 lesnik512 commented Sep 27, 2026 •

Copy link
Copy Markdown
Member

Closes #227.

OpenTelemetryInstrument.bootstrap() builds a provider and calls set_tracer_provider, which the
SDK enforces as set-once per process. When the application installed its own provider first the
call is refused, and the SDK's complaint goes to a logger _silence_otel_loggers() disabled two
lines earlier. Tracing still works, because every bootstrapper reads get_tracer_provider() when
it wires middleware, so the only casualty is invisible: the provider we built keeps the configured
exporter, sampler and resource, nothing will ever feed it a span, and its BatchSpanProcessor
worker thread and collector connection stay alive until teardown().

This makes that audible. It is a diagnostic, not a behaviour change.

set_tracer_provider(tracer_provider)
if get_tracer_provider() is not tracer_provider:
    warn_at_caller("a TracerProvider is already installed; ...")

UserWarning, matching the insecure-endpoint warning in OpenTelemetryConfig.__post_init__.
Deliberately not InstrumentSkippedWarning: the instrument did bootstrap and tracing works, and
pytest_configure escalates that class to an error, which would turn a diagnostic into a failure.

Still not proposed, per the issue: skipping provider construction when one already exists, which
would silently discard an explicit opentelemetry_endpoint.

The test suite had to change first

The suite never reset the process-global provider, so the first test to bootstrap owned it and
every later test silently lost the race. Measured with the warning in and no test changes:
70 of 331 tests emit it, across six files, and one fails outright
(test_swagger_warning_points_at_the_bootstrap_call_site, whose warning_source_files(...) == [__file__] suddenly sees two warnings).

An autouse fixture in tests/conftest.py now clears the global after each test, so each one starts
where a fresh process does. That drops the warners from 71 invocations to 2 and makes the suite
order-independent, which it was not before: 333 pass under -p no:randomly and under random order.

It reaches into opentelemetry.trace._TRACER_PROVIDER and _TRACER_PROVIDER_SET_ONCE because the
SDK offers no public reset. Both names are spelled identically at the 1.28 floor and at 1.44, and
if upstream ever moves them the fixture raises AttributeError rather than passing silently.

The two remaining warners are both correct, and each is now deliberate:

  • test_two_free_bootstrappers_both_bootstrap genuinely bootstraps twice, so it asserts the
    warning with pytest.warns.
  • test_pyroscope_otel_adds_span_processor_when_configured was a false positive: it patched
    set_tracer_provider out, so the global was never set and the identity check could not hold.
    The patch existed to stop that test polluting the global, which the fixture now handles properly,
    so it is gone.

Tests

Written failing first. test_bootstrap_warns_when_a_tracer_provider_is_already_installed
pre-installs a provider, then pins the exact message and, through warning_source_files, that the
warning is attributed to the caller's frame rather than to lite_bootstrap's own bootstrap().
test_bootstrap_is_silent_when_it_installs_the_tracer_provider covers the other branch, which the
100% gate requires.

Verified

eof-fixer --check, ruff format --check, ruff check --no-fix, ty check clean.
333 passed in both orders. Coverage 100.00%, gate satisfied.

The floors legs run scripts/floor_smoke.py, not pytest, so the conftest fixture never executes
there; what does is the library change, and get_tracer_provider is public and exported at the
1.28 API floor. Ran the free target locally at Python 3.10 with opentelemetry-api and -sdk pinned
to 1.28.0: floor smoke OK: free on 3.10.21, with the span emitted and the new branch quiet.

@lesnik512
lesnik512 merged commit d118c6a into main Sep 27, 2026
37 checks passed
@lesnik512
lesnik512 deleted the fix/227-warn-on-lost-tracer-provider branch September 27, 2026 18:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Losing the set_tracer_provider race leaves an orphaned provider and a live exporter thread, silently

1 participant