atexit.py 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. import os
  2. import sys
  3. import atexit
  4. import sentry_sdk
  5. from sentry_sdk.utils import logger
  6. from sentry_sdk.integrations import Integration
  7. from typing import TYPE_CHECKING
  8. if TYPE_CHECKING:
  9. from typing import Any
  10. from typing import Optional
  11. def default_callback(pending: int, timeout: int) -> None:
  12. """This is the default shutdown callback that is set on the options.
  13. It prints out a message to stderr that informs the user that some events
  14. are still pending and the process is waiting for them to flush out.
  15. """
  16. def echo(msg: str) -> None:
  17. sys.stderr.write(msg + "\n")
  18. echo("Sentry is attempting to send %i pending events" % pending)
  19. echo("Waiting up to %s seconds" % timeout)
  20. echo("Press Ctrl-%s to quit" % (os.name == "nt" and "Break" or "C"))
  21. sys.stderr.flush()
  22. class AtexitIntegration(Integration):
  23. identifier = "atexit"
  24. def __init__(self, callback: "Optional[Any]" = None) -> None:
  25. if callback is None:
  26. callback = default_callback
  27. self.callback = callback
  28. @staticmethod
  29. def setup_once() -> None:
  30. @atexit.register
  31. def _shutdown() -> None:
  32. client = sentry_sdk.get_client()
  33. integration = client.get_integration(AtexitIntegration)
  34. if integration is None:
  35. return
  36. logger.debug("atexit: got shutdown signal")
  37. logger.debug("atexit: shutting down client")
  38. sentry_sdk.get_isolation_scope().end_session()
  39. client.close(callback=integration.callback)