Profiling Django Projects with Cachegrind
Posted on January 20, 2011
Middleware
First, you have to collect profiling data with cProfile. Plug it into your Django project with a middleware class, such as this:
from datetime import datetime
import cProfile
class InstrumentMiddleware(object):
def process_request(self, request):
if 'profile' in request.COOKIES:
request.profiler = cProfile.Profile()
request.profiler.enable()
def process_response(self, request, response):
if hasattr(request, 'profiler'):
request.profiler.disable()
stamp = (request.META['REMOTE_ADDR'], datetime.now())
request.profiler.dump_stats('/tmp/%s-%s.pro' % stamp)
return response
This will start collecting data in process_request and stop collecting data in process_response thus monitoring the whole request. This includes all other middleware or some middleware depending where you put it in your settings.py:
MIDDLEWARE_CLASSES = (
...
'project.apps.myapp.middleware.InstrumentMiddleware',
...
Profile data
Next, collect the data for the page you want to profile. You will have to create a cookie in your browser called profile with whatever content. This is of course to prevent other pages from other users being profiled. You will find the profile data in the directory tmp on the server. Copy the file to your desktop.
Visualize
Install KCachegrind. I have not been able to find a substitute for this application so you will have to use that with all its KDE dependencies. Like this on Ubuntu:
apt-get install kcachegrind
Get pyprof2calltree, from pip, for example:
pip install pyprof2calltree
Last, run pyprof2calltree with the dump you have copied from the server. It will start KCachegrind automatically:
pyprof2calltree -i 123.124.125.126-2011-01-19\ 18\:49\:35.134598.pro -k
Enjoy
Now you should see your request analyzed in KCachegrind. Find where the problem is and charge your customer dearly.