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