Skip to content

Add sampler shutdown lifecycle - #5747

Open
Mayukhga83 wants to merge 4 commits into
open-telemetry:mainfrom
Mayukhga83:feat/sampler-shutdown-5713
Open

Mayukhga83 wants to merge 4 commits into
open-telemetry:mainfrom
Mayukhga83:feat/sampler-shutdown-5713

Conversation

@Mayukhga83

Copy link
Copy Markdown

Description

This PR adds a shutdown lifecycle to SDK samplers.

Sampler.shutdown() has a default no-op implementation so existing custom samplers remain compatible. TracerProvider.shutdown() now shuts down span processors first and then the configured sampler.

Wrapper samplers also forward shutdown to their delegates:

  • ParentBased shuts down each distinct directly wrapped sampler once.
  • AlwaysRecordSampler shuts down its root sampler.

Provider shutdown is idempotent, including when explicit shutdown and process-exit cleanup both occur. Cleanup is still attempted when another shutdown component raises an exception.

Part of #5713.

Assisted-by: ChatGPT

Type of change

  • Bug fix
  • New feature (non-breaking change)
  • Breaking change
  • This change requires a documentation update

How Has This Been Tested?

I added unit tests covering:

  • Existing custom samplers that do not override shutdown()
  • Shutdown propagation through ParentBased
  • Deduplication when a sampler occupies multiple ParentBased delegate positions
  • Shutdown propagation through AlwaysRecordSampler
  • Span-processor and sampler shutdown ordering
  • Explicit and process-exit shutdown
  • Repeated shutdown calls
  • Exceptions raised during processor or sampler shutdown

Validation performed:

  • 138 focused sampler and tracer-provider tests passed
  • 283 SDK trace tests passed
  • lint-opentelemetry-sdk passed

Does This PR Require a Contrib Repo Change?

  • Yes
    • The AWS X-Ray sampler will need a corresponding implementation in the contrib repository.
    • Follow-up PR: pending
  • No

Checklist

  • Followed the style guidelines of this project
  • Changelogs have been updated
  • Unit tests have been added
  • API documentation/docstrings have been updated

Forward shutdown through wrapper samplers and invoke it from TracerProvider with idempotent cleanup semantics.

Assisted-by: ChatGPT
@Mayukhga83
Mayukhga83 requested a review from a team as a code owner October 5, 2026 22:25
@linux-foundation-easycla

linux-foundation-easycla Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

CLA Signed
The committers listed above are authorized under a signed CLA.

  • ✅ login: Mayukhga83 / name: Mayukh Das (e776e0e)

@opentelemetry-pr-dashboard

opentelemetry-pr-dashboard Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

Pull request dashboard status

Waiting on the author · refreshed 2026-11-04 04:09 UTC

Respond to 4 review items (e.g. link a commit, explain why not, ask a follow-up):

  • Inline threads: 1, 2, 3, 4
Status above doesn't look right?
  • Just replied or pushed? Anything around or after the refresh time above may not be picked up yet — give it a few minutes.
  • Should this be with reviewers? Comment /dashboard route:reviewers to route it to them.
  • Anything wrong — including the routing? Report it with what you expected; it helps us improve the dashboard.

def get_description(self) -> str:
pass

def shutdown(self) -> None:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be private since it's developmental

@Mayukhga83 Mayukhga83 Oct 15, 2026 •

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed the developmental lifecycle hook to private _shutdown() and updated wrappers/tests

if self._shutdown:
return
self._shutdown = True
try:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: extract these into helpers to avoid nested try-finally

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extracted sampler shutdown and atexit cleanup into helpers, removing the nested try/finally while preserving cleanup behavior

@@ -1279,6 +1279,8 @@ def __init__(
self._disabled = disabled.lower().strip() == "true"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a changelog entry.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added .changelog/5747.added for the SDK sampler shutdown lifecycle

@opentelemetry-pr-dashboard

This comment has been minimized.

@Mayukhga83

Copy link
Copy Markdown
Author

Addressed the three review items in 17d8851. The focused tests pass: 137 passed, 1 platform-specific skip

@tammy-baylis-swi tammy-baylis-swi moved this from Reviewed PRs that need fixes to Ready for review in Python PR digest Oct 16, 2026

@tammy-baylis-swi tammy-baylis-swi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, this lgtm. Not sure why the changelog ci/cd is failing. Please could you Update Branch which might stop the symbol failure.

@tammy-baylis-swi tammy-baylis-swi moved this from Ready for review to Approved PRs in Python PR digest Oct 16, 2026
@tammy-baylis-swi

Copy link
Copy Markdown
Contributor

Update from main has fixed the ci/cd. 🙂 Maintainers ptal at the revisions made

@opentelemetry-pr-dashboard

This comment has been minimized.

@tammy-baylis-swi

Copy link
Copy Markdown
Contributor

/dashboard route:reviewers

@opentelemetry-pr-dashboard

Copy link
Copy Markdown

@tammy-baylis-swi, your reviewer-routing request was recorded; this pull request has the approvals it needs and is now waiting on maintainers. The handoff remains active across pushes until newer actionable human feedback arrives. Top-level feedback through this request will not return; unresolved review threads remain open.

@pmcollins pmcollins left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, LGTM overall. Added one comment.

for delegate in delegates:
if id(delegate) not in seen:
seen.add(id(delegate))
delegate._shutdown() # pylint: disable=protected-access

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this can raise an exception, in which case the remaining delegates won't be shut down. Can we catch any exceptions and continue shutting down remaining delegates, then handle the error?

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Shutdown bypasses the advertised public sampler hook, while delegate or processor failures can permanently prevent remaining resources from being cleaned up.

3 open issues
What changed in this PR

Adds a sampler shutdown lifecycle to the tracing SDK, supporting resource cleanup for samplers as requested in #5713.

Changes:

  • Adds a default no-op sampler cleanup hook and forwarding through wrapper samplers.
  • Makes provider shutdown idempotent and attempts sampler cleanup after span processors, including when processor shutdown raises.
  • Adds lifecycle tests and a changelog entry.
File Description
opentelemetry-sdk/​tests/​trace/​test_trace.py Tests shutdown ordering, repeated calls, exit cleanup, and failures.
opentelemetry-sdk/​tests/​trace/​test_sampling.py Tests default cleanup, wrapper forwarding, and delegate deduplication.
opentelemetry-sdk/​src/​opentelemetry/​sdk/​trace/​sampling.py Adds sampler cleanup hooks and wrapper propagation.
opentelemetry-sdk/​src/​opentelemetry/​sdk/​trace/​__init__.py Integrates sampler cleanup into guarded, once-only provider shutdown.
.changelog/​5747.added Announces the sampler shutdown lifecycle.

Review effort: Balanced

Comment on lines +1472 to +1474
self._shutdown = True
try:
self._active_span_processor.shutdown()
def get_description(self) -> str:
pass

def _shutdown(self) -> None:
Comment on lines +388 to +391
for delegate in delegates:
if id(delegate) not in seen:
seen.add(id(delegate))
delegate._shutdown() # pylint: disable=protected-access

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Approved PRs

Development

Successfully merging this pull request may close these issues.

6 participants