debug.py 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. # -*- coding: utf-8 -
  2. #
  3. # This file is part of gunicorn released under the MIT license.
  4. # See the NOTICE for more information.
  5. """The debug module contains utilities and functions for better
  6. debugging Gunicorn."""
  7. import sys
  8. import linecache
  9. import re
  10. import inspect
  11. __all__ = ['spew', 'unspew']
  12. _token_spliter = re.compile('\W+')
  13. class Spew(object):
  14. """
  15. """
  16. def __init__(self, trace_names=None, show_values=True):
  17. self.trace_names = trace_names
  18. self.show_values = show_values
  19. def __call__(self, frame, event, arg):
  20. if event == 'line':
  21. lineno = frame.f_lineno
  22. if '__file__' in frame.f_globals:
  23. filename = frame.f_globals['__file__']
  24. if (filename.endswith('.pyc') or
  25. filename.endswith('.pyo')):
  26. filename = filename[:-1]
  27. name = frame.f_globals['__name__']
  28. line = linecache.getline(filename, lineno)
  29. else:
  30. name = '[unknown]'
  31. try:
  32. src = inspect.getsourcelines(frame)
  33. line = src[lineno]
  34. except IOError:
  35. line = 'Unknown code named [%s]. VM instruction #%d' % (
  36. frame.f_code.co_name, frame.f_lasti)
  37. if self.trace_names is None or name in self.trace_names:
  38. print('%s:%s: %s' % (name, lineno, line.rstrip()))
  39. if not self.show_values:
  40. return self
  41. details = []
  42. tokens = _token_spliter.split(line)
  43. for tok in tokens:
  44. if tok in frame.f_globals:
  45. details.append('%s=%r' % (tok, frame.f_globals[tok]))
  46. if tok in frame.f_locals:
  47. details.append('%s=%r' % (tok, frame.f_locals[tok]))
  48. if details:
  49. print("\t%s" % ' '.join(details))
  50. return self
  51. def spew(trace_names=None, show_values=False):
  52. """Install a trace hook which writes incredibly detailed logs
  53. about what code is being executed to stdout.
  54. """
  55. sys.settrace(Spew(trace_names, show_values))
  56. def unspew():
  57. """Remove the trace hook installed by spew.
  58. """
  59. sys.settrace(None)