PageRenderTime 36ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/circuits/core/debugger.py

https://bitbucket.org/prologic/circuits/
Python | 134 lines | 96 code | 20 blank | 18 comment | 6 complexity | 67a55f8da57bc8052812471241ece1c1 MD5 | raw file
  1. # Module: debugger
  2. # Date: 2nd April 2006
  3. # Author: James Mills, prologic at shortcircuit dot net dot au
  4. """
  5. Debugger component used to debug each event in a system by printing
  6. each event to sys.stderr or to a Logger Component instance.
  7. """
  8. import os
  9. import sys
  10. from traceback import format_exc
  11. from signal import SIGINT, SIGTERM
  12. from .components import BaseComponent
  13. from .handlers import handler, reprhandler
  14. class Debugger(BaseComponent):
  15. """Create a new Debugger Component
  16. Creates a new Debugger Component that listens to all events in the system
  17. printing each event to sys.stderr or a Logger Component.
  18. :var IgnoreEvents: list of events (str) to ignore
  19. :var IgnoreChannels: list of channels (str) to ignore
  20. :var enabled: Enabled/Disabled flag
  21. :param log: Logger Component instance or None (*default*)
  22. """
  23. IgnoreEvents = ["generate_events"]
  24. IgnoreChannels = []
  25. def __init__(self, errors=True, events=True, file=None, logger=None,
  26. prefix=None, trim=None, **kwargs):
  27. "initializes x; see x.__class__.__doc__ for signature"
  28. super(Debugger, self).__init__()
  29. self._errors = errors
  30. self._events = events
  31. if isinstance(file, str):
  32. self.file = open(os.path.abspath(os.path.expanduser(file)), "a")
  33. elif hasattr(file, "write"):
  34. self.file = file
  35. else:
  36. self.file = sys.stderr
  37. self.logger = logger
  38. self.prefix = prefix
  39. self.trim = trim
  40. self.IgnoreEvents.extend(kwargs.get("IgnoreEvents", []))
  41. self.IgnoreChannels.extend(kwargs.get("IgnoreChannels", []))
  42. @handler("signal", channel="*")
  43. def _on_signal(self, signo, stack):
  44. if signo in [SIGINT, SIGTERM]:
  45. raise SystemExit(0)
  46. @handler("exception", channel="*", priority=100.0)
  47. def _on_exception(self, error_type, value, traceback,
  48. handler=None, fevent=None):
  49. if not self._errors:
  50. return
  51. s = []
  52. if handler is None:
  53. handler = ""
  54. else:
  55. handler = reprhandler(handler)
  56. msg = "ERROR {0:s} ({1:s}) ({2:s}): {3:s}\n".format(
  57. handler, repr(fevent), repr(error_type), repr(value)
  58. )
  59. s.append(msg)
  60. s.extend(traceback)
  61. s.append("\n")
  62. if self.logger is not None:
  63. self.logger.error("".join(s))
  64. else:
  65. try:
  66. self.file.write("".join(s))
  67. self.file.flush()
  68. except IOError:
  69. pass
  70. @handler(priority=101.0)
  71. def _on_event(self, event, *args, **kwargs):
  72. """Global Event Handler
  73. Event handler to listen to all events printing
  74. each event to self.file or a Logger Component instance
  75. by calling self.logger.debug
  76. """
  77. try:
  78. if not self._events:
  79. return
  80. channels = event.channels
  81. if event.name in self.IgnoreEvents:
  82. return
  83. if all(channel in self.IgnoreChannels for channel in channels):
  84. return
  85. s = repr(event)
  86. if self.prefix:
  87. s = "%s: %s" % (self.prefix, s)
  88. if self.trim:
  89. s = "%s ...>" % s[:self.trim]
  90. if self.logger is not None:
  91. self.logger.debug(s)
  92. else:
  93. self.file.write(s)
  94. self.file.write("\n")
  95. self.file.flush()
  96. except Exception as e:
  97. sys.stderr.write("ERROR (Debugger): {}".format(e))
  98. sys.stderr.write("{}".format(format_exc()))