Shutdown and Draining

Most SDKs use a background queue to send out events. Because the queue sends asynchronously in the background it means that some events might be lost if the application shuts down unexpectedly. To prevent this all SDKs provide mechanisms to cope with this.

Typically SDKs provide two ways to shut down: a controlled shutdown where the system will wait up to about two seconds to flush out events (configurable) and an uncontrolled shutdown (also referred to as “killing” the client).

The Python SDK automatically drains on shutdown unless the AtExitIntegration is removed or the shutdown_timeout config key is set to 0. To manually drain the client provides a close method:

from sentry_sdk import Hub

client = Hub.current.client
if client is not None:
    client.close(timeout=2.0)

The client provides a close method that optionally takes the time in milliseconds for how long it waits and will return a promise that resolves when everything was flushed or the timeout kicked in.

let client = Sentry.getCurrentHub().getClient();
if (client) {
  client.close(2000).then(function() {
    process.exit();
  });
}

The .NET SDK automatically shuts down and waits ShutdownTimeout seconds before that happens when the Init’s return value is disposed:

using (SentrySdk.Init(...))
{
    // App code
}

In case of an unhandled exception that will crash the app, the SDK automatically disposes itself.

When the Rust SDK initializes a guard is returned from the init function. The destructor will automatically wait shutdown_timeout seconds. This means you just need to hold on to the guard and make sure it disposes on shutdown. Alternatively the client can be closed:

use std::time::Duration;
use sentry::Hub;

if let Some(client) = Hub.current().client() {
    client.close(Some(Duration::from_secs(2)));
}

After shutdown the client cannot be used any more so make sure to only do that right before you shut down the application.

In this guide