Files
flask-debugtoolbar/flask_debugtoolbar/panels/profiler.py
Michael van Tellingen 1c594b9ba3 Attempt to fix the flask-debugtoolbar:
- Rename the package to flask_debugtoolbar
 - Fix importing of the panels so that the views in the panels are correctly registered in the blueprint


There is still one major problem in the sqlalchemy panel where we are not able to get the SQLAlchemy reference
2011-10-17 21:27:51 +02:00

117 lines
3.2 KiB
Python

import sys
try:
import cProfile as profile
except ImportError:
import profile
import functools
import os.path
import pstats
from flask import current_app
from flask_debugtoolbar.panels import DebugPanel
from flask_debugtoolbar.utils import format_fname
class ProfilerDebugPanel(DebugPanel):
"""
Panel that displays the time a response took with cProfile output.
"""
name = 'Profiler'
user_activate = True
def has_content(self):
return bool(self.profiler)
def process_request(self, request):
if not self.is_active:
return
self.profiler = profile.Profile()
self.stats = None
def process_view(self, request, view_func, view_kwargs):
if self.is_active:
return functools.partial(self.profiler.runcall, view_func)
def process_response(self, request, response):
if not self.is_active:
return False
if self.profiler is not None:
self.profiler.disable()
try:
stats = pstats.Stats(self.profiler)
except TypeError:
self.is_active = False
return False
function_calls = []
for func in stats.sort_stats(1).fcn_list:
current = {}
info = stats.stats[func]
# Number of calls
if info[0] != info[1]:
current['ncalls'] = '%d/%d' % (info[1], info[0])
else:
current['ncalls'] = info[1]
# Total time
current['tottime'] = info[2] * 1000
# Quotient of total time divided by number of calls
if info[1]:
current['percall'] = info[2] * 1000 / info[1]
else:
current['percall'] = 0
# Cumulative time
current['cumtime'] = info[3] * 1000
# Quotient of the cumulative time divded by the number of
# primitive calls.
if info[0]:
current['percall_cum'] = info[3] * 1000 / info[0]
else:
current['percall_cum'] = 0
# Filename
filename = pstats.func_std_string(func)
current['filename_long'] = filename
current['filename'] = format_fname(filename)
function_calls.append(current)
self.stats = stats
self.function_calls = function_calls
# destroy the profiler just in case
return response
def title(self):
if not self.is_active:
return "Profiler not active"
return 'View: %.2fms' % (float(self.stats.total_tt)*1000,)
def nav_title(self):
return 'Profiler'
def nav_subtitle(self):
if not self.is_active:
return "in-active"
return 'View: %.2fms' % (float(self.stats.total_tt)*1000,)
def url(self):
return ''
def content(self):
if not self.is_active:
return "The profiler is not activated, activate it to use it"
context = {
'stats': self.stats,
'function_calls': self.function_calls,
}
return self.render('panels/profiler.html', context)