/circuits/core/debugger.py
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 6""" 7Debugger component used to debug each event in a system by printing 8each event to sys.stderr or to a Logger Component instance. 9""" 10 11 12import os 13import sys 14from traceback import format_exc 15from signal import SIGINT, SIGTERM 16 17 18from .components import BaseComponent 19from .handlers import handler, reprhandler 20 21 22class Debugger(BaseComponent): 23 """Create a new Debugger Component 24 25 Creates a new Debugger Component that listens to all events in the system 26 printing each event to sys.stderr or a Logger Component. 27 28 :var IgnoreEvents: list of events (str) to ignore 29 :var IgnoreChannels: list of channels (str) to ignore 30 :var enabled: Enabled/Disabled flag 31 32 :param log: Logger Component instance or None (*default*) 33 """ 34 35 IgnoreEvents = ["generate_events"] 36 IgnoreChannels = [] 37 38 def __init__(self, errors=True, events=True, file=None, logger=None, 39 prefix=None, trim=None, **kwargs): 40 "initializes x; see x.__class__.__doc__ for signature" 41 42 super(Debugger, self).__init__() 43 44 self._errors = errors 45 self._events = events 46 47 if isinstance(file, str): 48 self.file = open(os.path.abspath(os.path.expanduser(file)), "a") 49 elif hasattr(file, "write"): 50 self.file = file 51 else: 52 self.file = sys.stderr 53 54 self.logger = logger 55 self.prefix = prefix 56 self.trim = trim 57 58 self.IgnoreEvents.extend(kwargs.get("IgnoreEvents", [])) 59 self.IgnoreChannels.extend(kwargs.get("IgnoreChannels", [])) 60 61 @handler("signal", channel="*") 62 def _on_signal(self, signo, stack): 63 if signo in [SIGINT, SIGTERM]: 64 raise SystemExit(0) 65 66 @handler("exception", channel="*", priority=100.0) 67 def _on_exception(self, error_type, value, traceback, 68 handler=None, fevent=None): 69 70 if not self._errors: 71 return 72 73 s = [] 74 75 if handler is None: 76 handler = "" 77 else: 78 handler = reprhandler(handler) 79 80 msg = "ERROR {0:s} ({1:s}) ({2:s}): {3:s}\n".format( 81 handler, repr(fevent), repr(error_type), repr(value) 82 ) 83 84 s.append(msg) 85 s.extend(traceback) 86 s.append("\n") 87 88 if self.logger is not None: 89 self.logger.error("".join(s)) 90 else: 91 try: 92 self.file.write("".join(s)) 93 self.file.flush() 94 except IOError: 95 pass 96 97 @handler(priority=101.0) 98 def _on_event(self, event, *args, **kwargs): 99 """Global Event Handler 100 101 Event handler to listen to all events printing 102 each event to self.file or a Logger Component instance 103 by calling self.logger.debug 104 """ 105 106 try: 107 if not self._events: 108 return 109 110 channels = event.channels 111 112 if event.name in self.IgnoreEvents: 113 return 114 115 if all(channel in self.IgnoreChannels for channel in channels): 116 return 117 118 s = repr(event) 119 120 if self.prefix: 121 s = "%s: %s" % (self.prefix, s) 122 123 if self.trim: 124 s = "%s ...>" % s[:self.trim] 125 126 if self.logger is not None: 127 self.logger.debug(s) 128 else: 129 self.file.write(s) 130 self.file.write("\n") 131 self.file.flush() 132 except Exception as e: 133 sys.stderr.write("ERROR (Debugger): {}".format(e)) 134 sys.stderr.write("{}".format(format_exc()))