1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
'''Profiling middleware for paste.'''
import cgi
import logging
import sys
import threading
from bzrlib.lsprof import profile
from guppy import hpy
class LSProfMiddleware(object):
'''Paste middleware for profiling with lsprof.'''
def __init__(self, app, global_conf=None):
self.app = app
self.lock = threading.Lock()
self.__count = 0
def __run_app(self, environ, start_response):
app_iter = self.app(environ, start_response)
try:
return list(app_iter)
finally:
if getattr(app_iter, 'close', None):
app_iter.close()
def __call__(self, environ, start_response):
"""Run a request."""
self.lock.acquire()
try:
ret, stats = profile(self.__run_app, environ, start_response)
self.__count += 1
stats.save("%d-stats.callgrind" % self.__count, format="callgrind")
return ret
finally:
self.lock.release()
class MemoryProfileMiddleware(object):
'''Paste middleware for profiling memory with heapy.'''
def __init__(self, app, limit=40):
self.app = app
self.lock = threading.Lock()
self.type2count = {}
self.type2all = {}
self.limit = limit
def update(self):
try:
obs = sys.getobjects(0)
except AttributeError:
logging.error(
'Python does not have debug symbols compiled. Memory will '
'not be profiled.')
return
type2count = {}
type2all = {}
for o in obs:
all = sys.getrefcount(o)
if type(o) is str and o == '<dummy key>':
# avoid dictionary madness
continue
t = type(o)
if t in type2count:
type2count[t] += 1
type2all[t] += all
else:
type2count[t] = 1
type2all[t] = all
ct = [(type2count[t] - self.type2count.get(t, 0),
type2all[t] - self.type2all.get(t, 0),
t)
for t in type2count.iterkeys()]
ct.sort()
ct.reverse()
printed = False
logger = logging.getLogger('loggerhead-memprofile')
logger.debug('*' * 20)
logger.debug("Loggerhead Memory Profiling")
i = 0
for delta1, delta2, t in ct:
if delta1 or delta2:
if not printed:
logger.debug("%-55s %8s %8s" % ('', 'insts', 'refs'))
printed = True
logger.debug("%-55s %8d %8d" % (t, delta1, delta2))
i += 1
if i >= self.limit:
break
self.type2count = type2count
self.type2all = type2all
def __call__(self, environ, start_response):
self.lock.acquire()
try:
# We don't want to be working with the static images
# TODO: There needs to be a better way to do this.
self.update()
return self.app(environ, start_response)
finally:
self.lock.release()
|