PageRenderTime 14ms CodeModel.GetById 1ms app.highlight 9ms RepoModel.GetById 1ms 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
  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()))