Question

I have a Django application which I decided to port to Google App Engine.
I decided to use NDB as my database and have ported all the models (including django user). After one week of reading through the documentation (the App Engine documentation is awful, the examples given are often outdated and don't work anymore) and porting the application, when I ran it it was really slow: 1s-2s latency with an empty database.
The ndb queries don't take much time (less then 50 ms) and the Appstats application doesn't show me anything else.
I decided to use cProfile and have created an wsgi middleware but I can't figure out how to print the output. The methods pstats gives me either prints the output or saves it to file and I can't do any inside the wsgi handler.
My code is as follows:

import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myapp.settings")
from django.core.handlers import wsgi

from webob import Request
class AppProfiler(object):  
    def __init__(self, app):
        self.app = app
    def __call__(self, environ, start_response):  
        from django.core.files.base import ContentFile 

        self.req = Request(environ)
        import cProfile, pstats
        prof = cProfile.Profile()
        prof = prof.runctx("self.get_resp()", globals(), locals())

        print "<pre>"
        stats = pstats.Stats(prof)
        #stats.dump_stats(output)
        stats.print_stats(80)
        print "</pre>"

        body = self.resp.body # here i should append the stats data
        self.resp.body = body

        return self.resp(environ, start_response)

    def get_resp(self):
        self.resp = self.req.get_response(self.app)

app = wsgi.WSGIHandler() 
profiler = AppProfiler(app)

How can I append the profiler stats to the body?
Or is there a better way to find out what is slowing down my application?
I'm using a lot of module imports in my django views is there an App Engine way to import modules?

Was it helpful?

Solution

There's already an awesome WSGI application that you can easily integrate in your project called google-app-engine-mini-profiler.

gae_mini_profiler is a quick drop-in WSGI app that provides ubiquitous profiling of your existing GAE projects. It exposes both RPC statistics and standard profiling output for users of your choosing on your production site. Only requests coming from users of your choosing will be profiled, and others will not suffer any performance degradation.

Please, have a look to this blog post by the author Ben Kamens or go straight to the repo.

OTHER TIPS

First, I don't think cProfile will work since it's a C library.

When you get around that, the simplest thing I can think of is to output your profiler data to the log.

import logging
logging.info("timing info")

1-2 seconds is not out of the ordinary for a startup request - ie if App Engine has to start up a new instance to handle your request. The logs will indicate which requests are startup requests.

If you are running many requests, and they still take that long, then there is a problem in your code somewhere.

you should use appstats. this tool is made exactly for this. https://developers.google.com/appengine/docs/python/tools/appstats

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top