/eventlet/debug.py

https://bitbucket.org/which_linden/eventlet-libevent · Python · 105 lines · 82 code · 10 blank · 13 comment · 14 complexity · cd8a7ef5a876ce47c89b1c4816d33a8f MD5 · raw file

  1. """The debug module contains utilities and functions for better
  2. debugging Eventlet-powered applications."""
  3. import os
  4. import sys
  5. import linecache
  6. __all__ = ['spew', 'unspew', 'format_hub_listeners', 'hub_listener_stacks',
  7. 'hub_exceptions', 'tpool_exceptions']
  8. class Spew(object):
  9. """
  10. """
  11. def __init__(self, trace_names=None, show_values=True):
  12. self.trace_names = trace_names
  13. self.show_values = show_values
  14. def __call__(self, frame, event, arg):
  15. if event == 'line':
  16. lineno = frame.f_lineno
  17. if '__file__' in frame.f_globals:
  18. filename = frame.f_globals['__file__']
  19. if (filename.endswith('.pyc') or
  20. filename.endswith('.pyo')):
  21. filename = filename[:-1]
  22. name = frame.f_globals['__name__']
  23. line = linecache.getline(filename, lineno)
  24. else:
  25. name = '[unknown]'
  26. try:
  27. src = inspect.getsourcelines(frame)
  28. line = src[lineno]
  29. except IOError:
  30. line = 'Unknown code named [%s]. VM instruction #%d' % (
  31. frame.f_code.co_name, frame.f_lasti)
  32. if self.trace_names is None or name in self.trace_names:
  33. print '%s:%s: %s' % (name, lineno, line.rstrip())
  34. if not self.show_values:
  35. return self
  36. details = '\t'
  37. tokens = line.translate(
  38. string.maketrans(' ,.()', '\0' * 5)).split('\0')
  39. for tok in tokens:
  40. if tok in frame.f_globals:
  41. details += '%s=%r ' % (tok, frame.f_globals[tok])
  42. if tok in frame.f_locals:
  43. details += '%s=%r ' % (tok, frame.f_locals[tok])
  44. if details.strip():
  45. print details
  46. return self
  47. def spew(trace_names=None, show_values=False):
  48. """Install a trace hook which writes incredibly detailed logs
  49. about what code is being executed to stdout.
  50. """
  51. sys.settrace(Spew(trace_names, show_values))
  52. def unspew():
  53. """Remove the trace hook installed by spew.
  54. """
  55. sys.settrace(None)
  56. def format_hub_listeners():
  57. """ Returns a formatted string of the current listeners on the current
  58. hub. This can be useful in determining what's going on in the event system,
  59. especially when used in conjunction with :func:`hub_listener_stacks`.
  60. """
  61. from eventlet import hubs
  62. hub = hubs.get_hub()
  63. result = ['READERS:']
  64. for l in hub.get_readers():
  65. result.append(repr(l))
  66. result.append('WRITERS:')
  67. for l in hub.get_writers():
  68. result.append(repr(l))
  69. return os.linesep.join(result)
  70. def hub_listener_stacks(state):
  71. """Toggles whether or not the hub records the stack when clients register
  72. listeners on file descriptors. This can be useful when trying to figure
  73. out what the hub is up to at any given moment. To inspect the stacks
  74. of the current listeners, call :func:`format_hub_listeners` at critical
  75. junctures in the application logic.
  76. """
  77. from eventlet import hubs
  78. hubs.get_hub().set_debug_listeners(state)
  79. def hub_exceptions(state):
  80. """Toggles whether the hub prints exceptions that are raised from its
  81. timers. This can be useful to see how greenthreads are terminating.
  82. """
  83. from eventlet import hubs
  84. hubs.get_hub().set_timer_exceptions(state)
  85. from eventlet import greenpool
  86. greenpool.DEBUG = state
  87. def tpool_exceptions(state):
  88. """Toggles whether tpool itself prints exceptions that are raised from
  89. functions that are executed in it, in addition to raising them like
  90. it normally does."""
  91. from eventlet import tpool
  92. tpool.QUIET = not state