Changeset 80

Show
Ignore:
Timestamp:
08/18/07 20:02:56 (1 year ago)
Author:
edsuom
Message:

Moving tracer to misc subpackage for general use beyond just WSGI debugging

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • projects/Twisted-Goodies/trunk/twisted_goodies/misc/__init__.py

    r2 r80  
    2323""" 
    2424 
    25 import struct, socket, new 
     25import struct, socket, new, sys 
    2626from twisted.internet import interfaces, defer 
    2727from twisted.spread import pb 
     
    196196        # The perspective is ready to give to the client 
    197197        return thisPerspective 
     198 
     199 
     200class TracerMixin(object): 
     201    """ 
     202    Mix me in to trace problems 
     203    """ 
     204    isTracing = False 
     205    traceFrame = None 
     206    traceStack = [ 
     207        # Bottom frame on up, just like a stack. The following items just 
     208        # represent an example that was used in Trac/WSGI debugging. 
     209        ('cache.py', 'get_changes'), 
     210        ('changeset.py', 'get_changes'), 
     211        ('changeset.py', '_render_html') 
     212        ] 
     213    traceLevels = 5 
     214     
     215    def settrace(self): 
     216        """ 
     217        Call this method to start tracing. If you're using threads, you must 
     218        call it within the same thread whose execution you want to trace. 
     219        """ 
     220        sys.settrace(self.trace) 
     221        self.isTracing = True 
     222 
     223    def trace(self, frame, event, arg): 
     224        """ 
     225        This is the actual trace function. 
     226        """ 
     227        def msg(level): 
     228            values = ["." * level] 
     229            values.extend([ 
     230                getattr(frame.f_code, "co_%s" % x) 
     231                for x in ('filename', 'firstlineno', 'name')]) 
     232            if values != getattr(self, '_prevMsgValues', None): 
     233                self._prevMsgValues = values 
     234                print "%s %s (%04d): %s" % tuple(values) 
     235 
     236        def isTraceEntry(k, thisFrame): 
     237            if thisFrame.f_code.co_name == self.traceStack[k][1]: 
     238                tail = "/%s" % self.traceStack[k][0] 
     239                if thisFrame.f_code.co_filename.endswith(tail): 
     240                    return True 
     241 
     242        def frameGenerator(N): 
     243            nextFrame = frame 
     244            for k in xrange(N): 
     245                yield k, nextFrame 
     246                nextFrame = nextFrame.f_back 
     247 
     248        if not self.isTracing: 
     249            return 
     250        if event == 'call': 
     251            level = 1 
     252            if self.traceFrame is None: 
     253                N = len(self.traceStack) 
     254                for k, thisFrame in frameGenerator(N): 
     255                    if not isTraceEntry(k, thisFrame): 
     256                        return 
     257                else: 
     258                    print "-" * 40 
     259                    self.traceFrame = frame 
     260            else: 
     261                for k, thisFrame in frameGenerator(self.traceLevels): 
     262                    level += 1 
     263                    if thisFrame in (None, self.traceFrame): 
     264                        break 
     265                else: 
     266                    return 
     267            msg(level) 
     268            return self.trace 
     269        elif event == 'return' and frame == self.traceFrame: 
     270            self.traceFrame = None 
     271            print "->", arg 
  • projects/Twisted-Goodies/trunk/twisted_goodies/simpleserver/http/wsgi.py

    r75 r80  
    2424""" 
    2525 
    26 import os, threading, sys 
     26import os, threading 
    2727import Queue 
    2828from zope.interface import implements 
     
    6161        newClass = super(WSGIMeta, mcls).__new__(mcls, name, bases, dictionary) 
    6262        return newClass 
    63  
    64  
    65 class TracerMixin(object): 
    66     """ 
    67     Mix me in to trace problems 
    68     """ 
    69     isTracing = False 
    70     traceFrame = None 
    71     traceStack = [ 
    72         # Bottom frame on up, just like a stack... 
    73         ('cache.py', 'get_changes'), 
    74         ('changeset.py', 'get_changes'), 
    75         ('changeset.py', '_render_html') 
    76         ] 
    77     traceLevels = 5 
    78      
    79     def settrace(self): 
    80         """ 
    81         Call this method to start tracing. If you're using threads, you must 
    82         call it within the same thread whose execution you want to trace. 
    83         """ 
    84         sys.settrace(self.trace) 
    85         self.isTracing = True 
    86  
    87     def trace(self, frame, event, arg): 
    88         """ 
    89         This is the actual trace function. 
    90         """ 
    91         def msg(level): 
    92             values = ["." * level] 
    93             values.extend([ 
    94                 getattr(frame.f_code, "co_%s" % x) 
    95                 for x in ('filename', 'firstlineno', 'name')]) 
    96             if values != getattr(self, '_prevMsgValues', None): 
    97                 self._prevMsgValues = values 
    98                 print "%s %s (%04d): %s" % tuple(values) 
    99  
    100         def isTraceEntry(k, thisFrame): 
    101             if thisFrame.f_code.co_name == self.traceStack[k][1]: 
    102                 tail = "/%s" % self.traceStack[k][0] 
    103                 if thisFrame.f_code.co_filename.endswith(tail): 
    104                     return True 
    105  
    106         def frameGenerator(N): 
    107             nextFrame = frame 
    108             for k in xrange(N): 
    109                 yield k, nextFrame 
    110                 nextFrame = nextFrame.f_back 
    111  
    112         if not self.isTracing: 
    113             return 
    114         if event == 'call': 
    115             level = 1 
    116             if self.traceFrame is None: 
    117                 N = len(self.traceStack) 
    118                 for k, thisFrame in frameGenerator(N): 
    119                     if not isTraceEntry(k, thisFrame): 
    120                         return 
    121                 else: 
    122                     print "-" * 40 
    123                     self.traceFrame = frame 
    124             else: 
    125                 for k, thisFrame in frameGenerator(self.traceLevels): 
    126                     level += 1 
    127                     if thisFrame in (None, self.traceFrame): 
    128                         break 
    129                 else: 
    130                     return 
    131             msg(level) 
    132             return self.trace 
    133         elif event == 'return' and frame == self.traceFrame: 
    134             self.traceFrame = None 
    135             print "->", arg 
    13663 
    13764