~mnordhoff/loggerhead/cheezum

« back to all changes in this revision

Viewing changes to loggerhead/middleware/profile.py

  • Committer: Matt Nordhoff
  • Date: 2009-04-22 20:10:50 UTC
  • mfrom: (164.96.2 dozer)
  • mto: This revision was merged to the branch mainline in revision 341.
  • Revision ID: mnordhoff@mattnordhoff.com-20090422201050-959trpseg3rgl9uo
Merge rockstar's Dozer patch, throwing out the changes to serve-branches.

Show diffs side-by-side

added added

removed removed

Lines of Context:
35
35
            self.lock.release()
36
36
 
37
37
 
38
 
class MemoryProfileMiddleware(object):
39
 
    '''Paste middleware for profiling memory with heapy.'''
40
 
 
41
 
    def __init__(self, app, limit=40):
42
 
        self.app = app
43
 
        self.lock = threading.Lock()
44
 
 
45
 
        self.type2count = {}
46
 
        self.type2all = {}
47
 
        self.limit = limit
48
 
 
49
 
    def update(self):
50
 
        try:
51
 
            obs = sys.getobjects(0)
52
 
        except AttributeError:
53
 
            logging.error(
54
 
                'Python does not have debug symbols compiled.  Memory will '
55
 
                'not be profiled.')
56
 
            return
57
 
        type2count = {}
58
 
        type2all = {}
59
 
        for o in obs:
60
 
            all = sys.getrefcount(o)
61
 
 
62
 
            if type(o) is str and o == '<dummy key>':
63
 
                # avoid dictionary madness
64
 
                continue
65
 
            t = type(o)
66
 
            if t in type2count:
67
 
                type2count[t] += 1
68
 
                type2all[t] += all
69
 
            else:
70
 
                type2count[t] = 1
71
 
                type2all[t] = all
72
 
 
73
 
        ct = [(type2count[t] - self.type2count.get(t, 0),
74
 
               type2all[t] - self.type2all.get(t, 0),
75
 
               t)
76
 
              for t in type2count.iterkeys()]
77
 
        ct.sort()
78
 
        ct.reverse()
79
 
        printed = False
80
 
 
81
 
        logger = logging.getLogger('loggerhead-memprofile')
82
 
        logger.debug('*' * 20)
83
 
        logger.debug("Loggerhead Memory Profiling")
84
 
        i = 0
85
 
        for delta1, delta2, t in ct:
86
 
            if delta1 or delta2:
87
 
                if not printed:
88
 
                    logger.debug("%-55s %8s %8s" % ('', 'insts', 'refs'))
89
 
                    printed = True
90
 
 
91
 
                logger.debug("%-55s %8d %8d" % (t, delta1, delta2))
92
 
 
93
 
                i += 1
94
 
                if i >= self.limit:
95
 
                    break
96
 
 
97
 
        self.type2count = type2count
98
 
        self.type2all = type2all
99
 
 
100
 
    def __call__(self, environ, start_response):
101
 
        self.lock.acquire()
102
 
        try:
103
 
            # We don't want to be working with the static images
104
 
            # TODO: There needs to be a better way to do this.
105
 
            self.update()
106
 
            return self.app(environ, start_response)
107
 
        finally:
108
 
            self.lock.release()
109