profiler.py (4571B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\lib\cherrypy\lib\profiler.py 2 3 4 def new_func_strip_path(func_name): 5 filename, line, name = func_name 6 if filename.endswith('__init__.py'): 7 return (os.path.basename(filename[:-12]) + filename[-12:], line, name) 8 return (os.path.basename(filename), line, name) 9 10 11 try: 12 import profile 13 import pstats 14 pstats.func_strip_path = new_func_strip_path 15 except ImportError: 16 profile = None 17 pstats = None 18 19 import os, os.path 20 import sys 21 import warnings 22 from cherrypy._cpcompat import BytesIO 23 _count = 0 24 25 class Profiler(object): 26 27 def __init__(self, path = None): 28 if not path: 29 path = os.path.join(os.path.dirname(__file__), 'profile') 30 self.path = path 31 if not os.path.exists(path): 32 os.makedirs(path) 33 34 def run(self, func, *args, **params): 35 global _count 36 c = _count = _count + 1 37 path = os.path.join(self.path, 'cp_%04d.prof' % c) 38 prof = profile.Profile() 39 result = prof.runcall(func, *args, **params) 40 prof.dump_stats(path) 41 return result 42 43 def statfiles(self): 44 return [ f for f in os.listdir(self.path) if f.startswith('cp_') and f.endswith('.prof') ] 45 46 def stats(self, filename, sortby = 'cumulative'): 47 sio = BytesIO() 48 if sys.version_info >= (2, 5): 49 s = pstats.Stats(os.path.join(self.path, filename), stream=sio) 50 s.strip_dirs() 51 s.sort_stats(sortby) 52 s.print_stats() 53 else: 54 s = pstats.Stats(os.path.join(self.path, filename)) 55 s.strip_dirs() 56 s.sort_stats(sortby) 57 oldout = sys.stdout 58 try: 59 sys.stdout = sio 60 s.print_stats() 61 finally: 62 sys.stdout = oldout 63 64 response = sio.getvalue() 65 sio.close() 66 return response 67 68 def index(self): 69 return "<html>\n <head><title>CherryPy profile data</title></head>\n <frameset cols='200, 1*'>\n <frame src='menu' />\n <frame name='main' src='' />\n </frameset>\n </html>\n " 70 71 index.exposed = True 72 73 def menu(self): 74 yield '<h2>Profiling runs</h2>' 75 yield '<p>Click on one of the runs below to see profiling data.</p>' 76 runs = self.statfiles() 77 runs.sort() 78 for i in runs: 79 yield "<a href='report?filename=%s' target='main'>%s</a><br />" % (i, i) 80 81 menu.exposed = True 82 83 def report(self, filename): 84 import cherrypy 85 cherrypy.response.headers['Content-Type'] = 'text/plain' 86 return self.stats(filename) 87 88 report.exposed = True 89 90 91 class ProfileAggregator(Profiler): 92 93 def __init__(self, path = None): 94 global _count 95 Profiler.__init__(self, path) 96 self.count = _count = _count + 1 97 self.profiler = profile.Profile() 98 99 def run(self, func, *args): 100 path = os.path.join(self.path, 'cp_%04d.prof' % self.count) 101 result = self.profiler.runcall(func, *args) 102 self.profiler.dump_stats(path) 103 return result 104 105 106 class make_app: 107 108 def __init__(self, nextapp, path = None, aggregate = False): 109 if profile is None or pstats is None: 110 msg = "Your installation of Python does not have a profile module. If you're on Debian, try `sudo apt-get install python-profiler`. See http://www.cherrypy.org/wiki/ProfilingOnDebian for details." 111 warnings.warn(msg) 112 self.nextapp = nextapp 113 self.aggregate = aggregate 114 if aggregate: 115 self.profiler = ProfileAggregator(path) 116 else: 117 self.profiler = Profiler(path) 118 119 def __call__(self, environ, start_response): 120 121 def gather(): 122 result = [] 123 for line in self.nextapp(environ, start_response): 124 result.append(line) 125 126 return result 127 128 return self.profiler.run(gather) 129 130 131 def serve(path = None, port = 8080): 132 if profile is None or pstats is None: 133 msg = "Your installation of Python does not have a profile module. If you're on Debian, try `sudo apt-get install python-profiler`. See http://www.cherrypy.org/wiki/ProfilingOnDebian for details." 134 warnings.warn(msg) 135 import cherrypy 136 cherrypy.config.update({'server.socket_port': int(port), 137 'server.thread_pool': 10, 138 'environment': 'production'}) 139 cherrypy.quickstart(Profiler(path)) 140 141 142 if __name__ == '__main__': 143 serve(*tuple(sys.argv[1:]))