IMPORTANT: This article is being preserved for historical purposes and likely no longer reflects the state of AT-SPI over D-Bus.

   1 Index: pyatspi/registry.py
   2 ===================================================================
   3 --- pyatspi/registry.py (revision 966)
   4 +++ pyatspi/registry.py (working copy)
   5 @@ -42,6 +42,8 @@
   6  import constants
   7  import event
   8  
   9 +from atspilogger import LOG_OBJ
  10 +
  11  class _Observer(object):
  12    '''
  13    Parent class for all event observers. Dispatches all received events to the 
  14 @@ -635,6 +637,8 @@
  15      consume = False
  16      for client in clients:
  17        try:
  18 +        #Code for logging event goes here.
  19 +       LOG_OBJ.log(client.__name__, "notifyEvent", event.type, "")
  20          consume = client(event) or False
  21        except Exception:
  22          # print the exception, but don't let it stop notification
  23 Index: pyatspi/accessible.py
  24 ===================================================================
  25 --- pyatspi/accessible.py       (revision 966)
  26 +++ pyatspi/accessible.py       (working copy)
  27 @@ -45,6 +45,7 @@
  28  import constants
  29  import utils
  30  import registry
  31 +from atspilogger import makeLoggedFunction
  32  
  33  _ACCESSIBLE_CACHE = {}
  34  _CACHE_LEVEL = None
  35 @@ -180,6 +181,7 @@
  36    @return: Function calling the method being wrapped
  37    @rtype: function
  38    '''
  39 +  func = makeLoggedFunction(func)
  40    def _inner(self, *args, **kwargs):
  41      try:
  42        # try calling the original func
  43 Index: pyatspi/atspilogparser.py
  44 ===================================================================
  45 --- pyatspi/atspilogparser.py   (revision 0)
  46 +++ pyatspi/atspilogparser.py   (revision 0)
  47 @@ -0,0 +1,60 @@
  48 +"""
  49 +Convert an atspi message log.
  50 +
  51 +Usage:
  52 +       atspilogparser filename
  53 +"""
  54 +import sys
  55 +
  56 +def logMessageIterator(filename):
  57 +       """
  58 +       Outputs a sequence of log message tuples from a file.
  59 +       """
  60 +       ofile = open(filename, 'r')
  61 +       for line in ofile:
  62 +               time, objectref, method, args, result = line.split(',') 
  63 +               argl = args.split(' ')
  64 +               yield (time, objectref, method, argl, result)
  65 +       ofile.close()
  66 +
  67 +def getMethodFrequencies(filename):
  68 +       """
  69 +       Ouputs the method call frequencies found in a message log.
  70 +       """
  71 +       histfilename = filename + ".hist"
  72 +       histfile = open(histfilename, 'w')
  73 +       histMeth = {}
  74 +       total = 0
  75 +       for time, objectref, method, argl, result in logMessageIterator(filename):
  76 +               if method not in histMeth:
  77 +                       histMeth[method] = 1
  78 +               else:
  79 +                       histMeth[method] += 1
  80 +               total += 1
  81 +
  82 +       for key, value in histMeth.items():
  83 +               perc = (float(value) / float(total)) * 100
  84 +               histfile.write("%s - %f\n" % (key, perc))
  85 +       histfile.write("\n\nTotal: %d" % (total))
  86 +       histfile.close()
  87 +
  88 +def getCsv(filename):
  89 +       """
  90 +       Ouputs the log file in CSV format.
  91 +       """
  92 +       csvfilename = filename + ".csv"
  93 +       csvfile = open(csvfilename, 'w')
  94 +       for time, objectref, method, argl, result in logMessageIterator(filename):
  95 +               argstr = ' '.join(argl)
  96 +               record = ['"'+s.strip()+'"' for s in (time, objectref, method, argstr, result)]
  97 +               line = ','.join(record)
  98 +               csvfile.write(line + '\n')
  99 +       csvfile.close()
 100 +
 101 +def main(argv):
 102 +       filename = argv[1]
 103 +       #getMethodFrequencies(filename)
 104 +       getCsv(filename)
 105 +
 106 +if __name__ == "__main__":
 107 +       sys.exit(main(sys.argv))
 108 Index: pyatspi/atspilogger.py
 109 ===================================================================
 110 --- pyatspi/atspilogger.py      (revision 0)
 111 +++ pyatspi/atspilogger.py      (revision 0)
 112 @@ -0,0 +1,99 @@
 113 +"""
 114 +class - ATSPILogger, logs method calls with timestamp
 115 +object - LOG_OBJ, singleton object of ATSPILogger
 116 +"""
 117 +from time import time
 118 +import os
 119 +
 120 +class ATSPILogger(object):
 121 +       """
 122 +       Singleton logging object for all at-spi messages.       
 123 +
 124 +       Messages are logged to memory and then output either on
 125 +       calling output method or logger object destruction.
 126 +       """
 127 +       __single = None
 128 +
 129 +       def __init__(self):
 130 +               if ATSPILogger.__single:
 131 +                       raise ATSPILogger.__single
 132 +               self.__logarray = []
 133 +               self.__lognumber = 1
 134 +               if 'ATSPILOG_OFF' in os.environ:
 135 +                       self.__enable = False
 136 +               else:
 137 +                       self.__enable = True
 138 +
 139 +       def log(self, objectref, method, args, result):
 140 +               """
 141 +               string - object reference
 142 +               string - method name
 143 +               [string] - list of arg
 144 +               string - result of method call
 145 +               """
 146 +               if self.__enable:
 147 +                       self.__logarray.append((str(time()), objectref, method, args, result))
 148 +
 149 +       def output(self):
 150 +               """
 151 +               Outputs log to files.
 152 +
 153 +               env{ATSPILOG} - All method calls and time called
 154 +               """
 155 +               print "ATSPILOG Output to file"
 156 +               outfile = open(self.__outfilename(), 'w')
 157 +               for t, objectref, method, args, result in self.__logarray:
 158 +                       #Write out to a file
 159 +                       argstr = ' '.join(args)
 160 +                       outfile.write(','.join((t, objectref, method, argstr, result)) + '\n')
 161 +               outfile.close
 162 +
 163 +       def clear(self):
 164 +               print "ATSPILOG Clearing data"
 165 +               self.__logarray = []
 166 +
 167 +       def __outfilename(self):
 168 +               try:
 169 +                       outfilename = os.environ.get['ATSPILOG']
 170 +               except:
 171 +                       outfilename = 'atspi-calls-%d.log' % self.__lognumber
 172 +               self.__lognumber += 1
 173 +               return outfilename
 174 +
 175 +       def getEnable(self):
 176 +               return self.__enable
 177 +
 178 +       def setEnable(self, enable):
 179 +               if enable == False and self.__enable == True:
 180 +                       self.output()
 181 +               if enable == True and self.__enable == False:
 182 +                       self.clear()
 183 +               self.__enable = enable
 184 +
 185 +       enable = property(getEnable, setEnable)
 186 +
 187 +       def __del__(self):
 188 +               if self.__enable:
 189 +                       self.output()
 190 +
 191 +GET_NAMES = False
 192 +LOG_OBJ = ATSPILogger()
 193 +
 194 +def makeLoggedFunction(func):
 195 +       """
 196 +       Wraps function call in code to log the parameters of the call
 197 +       to an ATSPILogger.
 198 +       """
 199 +       def _inner(self, *args, **kwargs):
 200 +               strargs = [str(arg) for arg in args]
 201 +               result = func(self, *args, **kwargs)
 202 +               repr = self.__repr__()
 203 +               rerepr = result.__repr__()
 204 +               if GET_NAMES:
 205 +                       if hasattr(self, 'name'):
 206 +                               rerepr = result.name + ':' + rerepr
 207 +                       if hasattr(result, 'name'):
 208 +                               rerepr = result.name + ':' + rerepr
 209 +               LOG_OBJ.log(repr, func.__name__, strargs, rerepr) 
 210 +               return result
 211 +       return _inner

Accessibility/Documentation/GNOME2/ATSPI2-Investigation/PyAtSpiLogging (last edited 2011-07-21 18:14:01 by JoanmarieDiggs)