debuglog.py 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  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, default
  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(
  31. log_path, 'w', 'utf8', delay=True)
  32. _log_formatter = self._log_formatter_cls(fmt=self.log_format, datefmt=self.log_datefmt)
  33. _debug_handler.setFormatter(_log_formatter)
  34. _debug_handler.setLevel('DEBUG')
  35. log.addHandler(_debug_handler)
  36. try:
  37. yield
  38. except Exception as ex:
  39. _, _, exc_traceback = sys.exc_info()
  40. msg = traceback.format_exception(ex.__class__, ex, exc_traceback)
  41. for line in msg:
  42. self.log.debug(line)
  43. if isinstance(ex, SystemExit):
  44. print('An error occured. See the log file for details: ', log_path)
  45. raise
  46. print('An error occured.')
  47. print(msg[-1].strip())
  48. print('See the log file for details: ', log_path)
  49. self.exit(1)
  50. else:
  51. log.removeHandler(_debug_handler)
  52. _debug_handler.flush()
  53. _debug_handler.close()
  54. try:
  55. os.remove(log_path)
  56. except FileNotFoundError:
  57. pass
  58. log.removeHandler(_debug_handler)