Download Install Tutorial Docs FAQ Tools WikiLicense Team IRC Planet Involvement Shop Book

root/tags/cherrypy-3.0.0/cherrypy/lib/profiler.py

Revision 1281 (checked in by fumanchu, 2 years ago)

API and docstring cleanups:

  1. Removed WrongConfigValue?, decorate, decorate_all, and ExposeItems.
  2. Moved cherrypy.logtime to cherrypy.log.time.
  3. Reduced cherrypy.config.globalconf back to just cherrypy.config.
  4. Moved _cpconfig.default_conf to config.defaults.

.

  • Property svn:eol-style set to native
Line 
1 """Profiler tools for CherryPy.
2
3 CherryPy users
4 ==============
5
6 You can profile any of your pages as follows:
7
8     from cherrypy.lib import profiler
9     
10     class Root:
11         p = profile.Profiler("/path/to/profile/dir")
12         
13         def index(self):
14             self.p.run(self._index)
15         index.exposed = True
16         
17         def _index(self):
18             return "Hello, world!"
19     
20     cherrypy.tree.mount(Root())
21
22
23 You can also turn on profiling for all requests
24 using the make_app function as WSGI middleware.
25
26
27 CherryPy developers
28 ===================
29
30 This module can be used whenever you make changes to CherryPy,
31 to get a quick sanity-check on overall CP performance. Use the
32 "--profile" flag when running the test suite. Then, use the serve()
33 function to browse the results in a web browser. If you run this
34 module from the command line, it will call serve() for you.
35
36 """
37
38
39 # Make profiler output more readable by adding __init__ modules' parents.
40 def new_func_strip_path(func_name):
41     filename, line, name = func_name
42     if filename.endswith("__init__.py"):
43         return os.path.basename(filename[:-12]) + filename[-12:], line, name
44     return os.path.basename(filename), line, name
45
46 try:
47     import profile
48     import pstats
49     pstats.func_strip_path = new_func_strip_path
50 except ImportError:
51     profile = None
52     pstats = None
53     import warnings
54     msg = ("Your installation of Python does not have a profile module. "
55            "If you're on Debian, you can apt-get python2.4-profiler from "
56            "non-free in a separate step. See http://www.cherrypy.org/wiki/"
57            "ProfilingOnDebian for details.")
58     warnings.warn(msg)
59
60 import os, os.path
61 import sys
62
63 try:
64     import cStringIO as StringIO
65 except ImportError:
66     import StringIO
67
68
69 _count = 0
70
71 class Profiler(object):
72    
73     def __init__(self, path=None):
74         if not path:
75             path = os.path.join(os.path.dirname(__file__), "profile")
76         self.path = path
77         if not os.path.exists(path):
78             os.makedirs(path)
79    
80     def run(self, func, *args):
81         """run(func, *args). Run func, dumping profile data into self.path."""
82         global _count
83         c = _count = _count + 1
84         path = os.path.join(self.path, "cp_%04d.prof" % c)
85         prof = profile.Profile()
86         result = prof.runcall(func, *args)
87         prof.dump_stats(path)
88         return result
89    
90     def statfiles(self):
91         """statfiles() -> list of available profiles."""
92         return [f for f in os.listdir(self.path)
93                 if f.startswith("cp_") and f.endswith(".prof")]
94    
95     def stats(self, filename, sortby='cumulative'):
96         """stats(index) -> output of print_stats() for the given profile."""
97         s = pstats.Stats(os.path.join(self.path, filename))
98         s.strip_dirs()
99         s.sort_stats(sortby)
100         oldout = sys.stdout
101         try:
102             sys.stdout = sio = StringIO.StringIO()
103             s.print_stats()
104         finally:
105             sys.stdout = oldout
106         response = sio.getvalue()
107         sio.close()
108         return response
109    
110     def index(self):
111         return """<html>
112         <head><title>CherryPy profile data</title></head>
113         <frameset cols='200, 1*'>
114             <frame src='menu' />
115             <frame name='main' src='' />
116         </frameset>
117         </html>
118         """
119     index.exposed = True
120    
121     def menu(self):
122         yield "<h2>Profiling runs</h2>"
123         yield "<p>Click on one of the runs below to see profiling data.</p>"
124         runs = self.statfiles()
125         runs.sort()
126         for i in runs:
127             yield "<a href='report?filename=%s' target='main'>%s</a><br />" % (i, i)
128     menu.exposed = True
129    
130     def report(self, filename):
131         import cherrypy
132         cherrypy.response.headers['Content-Type'] = 'text/plain'
133         return self.stats(filename)
134     report.exposed = True
135
136
137 class ProfileAggregator(Profiler):
138    
139     def __init__(self, path=None):
140         Profiler.__init__(self, path)
141         global _count
142         self.count = _count = _count + 1
143         self.profiler = profile.Profile()
144    
145     def run(self, func, *args):
146         path = os.path.join(self.path, "cp_%04d.prof" % self.count)
147         result = self.profiler.runcall(func, *args)
148         self.profiler.dump_stats(path)
149         return result
150
151
152 class make_app:
153     def __init__(self, nextapp, path=None, aggregate=False):
154         """Make a WSGI middleware app which wraps 'nextapp' with profiling."""
155         self.nextapp = nextapp
156         self.aggregate = aggregate
157         if aggregate:
158             self.profiler = ProfileAggregator(path)
159         else:
160             self.profiler = Profiler(path)
161    
162     def __call__(self, environ, start_response):
163         def gather():
164             result = []
165             for line in self.nextapp(environ, start_response):
166                 result.append(line)
167             return result
168         return self.profiler.run(gather)
169
170
171 def serve(path=None, port=8080):
172     import cherrypy
173     cherrypy.config.update({'server.socket_port': int(port),
174                             'server.thread_pool': 10,
175                             'environment': "production",
176                             })
177     cherrypy.quickstart(Profiler(path))
178
179
180 if __name__ == "__main__":
181     serve(*tuple(sys.argv[1:]))
182
Note: See TracBrowser for help on using the browser.

Hosted by WebFaction

Log in as guest/cpguest to create tickets