debug.py 2.2 KB

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