bbangert / dozer


WSGI middleware fork of Robert Brewer's Dowser
Clone URL : http://bitbucket.org/bbangert/dozer/ (size: 146.1 KB)
commit 36: f1f70b805ed4
parent 30: 8b8e6861e08f
branch: trunk
added delete and show all actions
zepolen@armor
4 months ago

Changed (Δ1.0 KB):

raw changeset »

dozer/profile.py (41 lines added, 11 lines removed)

Up to file-list dozer/profile.py:

@@ -50,14 +50,14 @@ class Profiler(object):
50
50
        if not getattr(method, 'exposed', False):
51
51
            return exc.HTTPForbidden('Access to %r is forbidden' % next_part)
52
52
        return method(req)
53
    
53
54
54
    def media(self, req):
55
55
        """Static path where images and other files live"""
56
56
        path = resource_filename('dozer', 'media')
57
57
        app = urlparser.StaticURLParser(path)
58
58
        return app
59
59
    media.exposed = True
60
    
60
61
61
    def show(self, req):
62
62
        profile_id = req.path_info_pop()
63
63
        if not profile_id:
@@ -73,10 +73,40 @@ class Profiler(object):
73
73
        return res
74
74
    show.exposed = True
75
75
76
    def all(self, req):
77
        dir_name = self.profile_path
78
        link = '<a href="/_profiler/show/%(pid)s">%(pid)s</a>'
79
        profiles = []
80
        for profile_file in os.listdir(dir_name):
81
            if profile_file.endswith('.pkl'):
82
                modified = os.stat(
83
                    os.path.join(self.profile_path, profile_file)
84
                    ).st_mtime
85
                profiles.append((modified, profile_file))
86
        profiles.sort(reverse=True)
87
        res = Response()
88
        if profiles:
89
            delete_link = ['<a href="/_profiler/delete">delete all profiles</a>']
90
            res.body = '<br>'.join(delete_link + [link % {'pid': name[:-4]} for (m, name) in profiles])
91
        else:
92
            res.body = 'no profiles'
93
        return res
94
    all.exposed = True
95
96
    def delete(self, req):
97
        for filename in os.listdir(self.profile_path):
98
            if filename.endswith('.pkl') or filename.endswith('.gz'):
99
                os.unlink(os.path.join(self.profile_path, filename))
100
        res = Response()
101
        res.location = '/_profiler/all'
102
        res.status_int = 302
103
        return res
104
105
76
106
    def render(self, name, **vars):
77
107
        tmpl = self.mako.get_template(name)
78
108
        return tmpl.render(**vars)
79
    
109
80
110
    def run_profile(self, environ, start_response):
81
111
        """Run the profile over the request and save it"""
82
112
        prof = cProfile.Profile()
@@ -98,7 +128,7 @@ class Profiler(object):
98
128
        body = ''.join(response_body)
99
129
        results = prof.getstats()
100
130
        tree = buildtree(results)
101
        
131
102
132
        # Pull out 'safe' bits from environ
103
133
        safe_environ = {}
104
134
        for k, v in environ.iteritems():
@@ -112,7 +142,7 @@ class Profiler(object):
112
142
                           environ=safe_environ)
113
143
        fname_base = str(time.time()).replace('.', '_')
114
144
        prof_file = fname_base + '.pkl'
115
        
145
116
146
        dir_name = self.profile_path or ''
117
147
        cPickle.dump(profile_run, open(os.path.join(dir_name, prof_file), 'wb'))
118
148
        write_dot_graph(results, tree, os.path.join(dir_name, fname_base+'.gv'))
@@ -138,13 +168,13 @@ def setup_time(t):
138
168
def setup_time(t):
139
169
    """Takes a time generally assumed to be quite small and blows it
140
170
    up into millisecond time.
141
    
171
142
172
    For example:
143
173
        0.004 seconds     -> 4 ms
144
174
        0.00025 seconds   -> 0.25 ms
145
    
175
146
176
    The result is returned as a string.
147
    
177
148
178
    """
149
179
    t = t*1000
150
180
    t = '%0.2f' % t
@@ -155,13 +185,13 @@ def write_dot_graph(data, tree, filename
155
185
    f.write('digraph prof {\n')
156
186
    f.write('\tsize="11,9"; ratio = fill;\n')
157
187
    f.write('\tnode [style=filled];\n')
158
    
188
159
189
    # Find the largest time
160
190
    highest = 0.00
161
191
    for entry in tree.values():
162
192
        if float(entry['cost']) > highest:
163
193
            highest = float(entry['cost'])
164
    
194
165
195
    for entry in data:
166
196
        code = entry.code
167
197
        entry_name = graphlabel(code)
@@ -203,7 +233,7 @@ def buildtree(data):
203
233
            node['line_no'] = code.co_firstlineno
204
234
        node['cost'] = setup_time(entry.totaltime)
205
235
        node['function'] = label(code)
206
        
236
207
237
        if entry.calls:
208
238
            for subentry in entry.calls:
209
239
                subnode = {}