Skip to content

fix: shut down TracerProvider in OpenTelemetryInstrument.teardown#90

Merged
lesnik512 merged 1 commit into
mainfrom
fix/crit-2-otel-shutdown
May 31, 2026
Merged

fix: shut down TracerProvider in OpenTelemetryInstrument.teardown#90
lesnik512 merged 1 commit into
mainfrom
fix/crit-2-otel-shutdown

Conversation

@lesnik512
Copy link
Copy Markdown
Member

@lesnik512 lesnik512 commented May 31, 2026

Summary

  • OpenTelemetryInstrument.bootstrap() now stashes the TracerProvider it created on the instance (via object.__setattr__, mirroring LoggingInstrument._logger_factory).
  • teardown() calls self._tracer_provider.shutdown() after the existing instrumentor uninstrument loop, then resets the field to None. Spans buffered in BatchSpanProcessor now flush on graceful shutdown.
  • New regression test test_opentelemetry_instrument_teardown_shuts_down_tracer_provider patches shutdown on the stashed provider and asserts it's invoked once and the field resets. Test fails on main, passes on this branch.

Closes CRIT-2 and TEST-2 from an internal audit of the codebase.

Test plan

  • just test -- tests/instruments/test_opentelemetry_instrument.py -v — three tests pass.
  • just test — full suite 80/80.
  • just lint — clean (eof-fixer, ruff format, ruff check, ty check).
  • Reviewer: confirm the field declaration and object.__setattr__ usage match the LoggingInstrument._logger_factory precedent.

Known follow-up

If shutdown() raises, _tracer_provider is left non-None — same shape as LoggingInstrument.teardown (also a pre-existing pattern). The follow-up idempotency work (a separate PR addressing CRIT-3 from the audit) should wrap both teardowns in try/finally so a failed shutdown still resets the cached reference.

🤖 Generated with Claude Code

The instrument's bootstrap() created a TracerProvider, registered span
processors against it, and called set_tracer_provider — but never stored
a reference. teardown() only uninstrumented the instrumentors; the
provider was never shut down. Spans buffered in BatchSpanProcessor were
lost on graceful shutdown.

Stash the provider on the instrument via object.__setattr__ (mirroring
the LoggingInstrument._logger_factory pattern for runtime state on a
frozen dataclass), shut it down after the uninstrument loop, reset the
field to None so a subsequent bootstrap starts clean.

Regression test asserts shutdown is called exactly once on the stored
provider and the field is reset.

Closes CRIT-2, TEST-2 from the audit.
@codecov
Copy link
Copy Markdown

codecov Bot commented May 31, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

Flag Coverage Δ
unittests 100.00% <100.00%> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
..._bootstrap/instruments/opentelemetry_instrument.py 100.00% <100.00%> (ø)
tests/instruments/test_opentelemetry_instrument.py 100.00% <100.00%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@lesnik512 lesnik512 merged commit 7f3148f into main May 31, 2026
8 checks passed
@lesnik512 lesnik512 deleted the fix/crit-2-otel-shutdown branch May 31, 2026 20:42
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.

1 participant