debuglog.py 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. """A mixin for adding a debug log file."""
  2. # Copyright (c) Jupyter Development Team.
  3. # Distributed under the terms of the Modified BSD License.
  4. import contextlib
  5. import logging
  6. import os
  7. import sys
  8. import tempfile
  9. import traceback
  10. import warnings
  11. from traitlets import Unicode
  12. from traitlets.config import Configurable
  13. class DebugLogFileMixin(Configurable):
  14. debug_log_path = Unicode("", config=True, help="Path to use for the debug log file")
  15. @contextlib.contextmanager
  16. def debug_logging(self):
  17. log_path = self.debug_log_path
  18. if os.path.isdir(log_path):
  19. log_path = os.path.join(log_path, "jupyterlab-debug.log")
  20. if not log_path:
  21. handle, log_path = tempfile.mkstemp(prefix="jupyterlab-debug-", suffix=".log")
  22. os.close(handle)
  23. log = self.log
  24. # Transfer current log level to the handlers:
  25. for h in log.handlers:
  26. h.setLevel(self.log_level)
  27. log.setLevel("DEBUG")
  28. # Create our debug-level file handler:
  29. _debug_handler = logging.FileHandler(log_path, "w", "utf8", delay=True)
  30. _log_formatter = self._log_formatter_cls(fmt=self.log_format, datefmt=self.log_datefmt)
  31. _debug_handler.setFormatter(_log_formatter)
  32. _debug_handler.setLevel("DEBUG")
  33. log.addHandler(_debug_handler)
  34. try:
  35. yield
  36. except Exception as ex:
  37. _, _, exc_traceback = sys.exc_info()
  38. msg = traceback.format_exception(ex.__class__, ex, exc_traceback)
  39. for line in msg:
  40. self.log.debug(line)
  41. if isinstance(ex, SystemExit):
  42. warnings.warn(f"An error occurred. See the log file for details: {log_path!s}")
  43. raise
  44. warnings.warn("An error occurred.")
  45. warnings.warn(msg[-1].strip())
  46. warnings.warn(f"See the log file for details: {log_path!s}")
  47. self.exit(1)
  48. else:
  49. log.removeHandler(_debug_handler)
  50. _debug_handler.flush()
  51. _debug_handler.close()
  52. try:
  53. os.remove(log_path)
  54. except FileNotFoundError:
  55. pass
  56. log.removeHandler(_debug_handler)