debuglog.py 2.1 KB

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