3

I want to optimize my django application, to do so, I use django_debug_toolbar to know what SQL resquests are done to compute a html page. I want to do the same thing for opened files : is there a django_debug_toolbar pluggin or is there a way to develop a django middleware to keep track the opened files during a html page request ?

Eric
  • 4,821
  • 6
  • 33
  • 60
  • I did not use django_debug_toolbar but you can simply have list of opened files - you can simply catch all calls to os.open (register them and forward to original function) – ddzialak Aug 27 '12 at 13:53
  • Do you mean how to track the opened static files(e.g., JS/CSS/Images) ? Django is a framework used to build ***dynamic*** web application. By ***dynamic*** it means there are hardly cases of directly read/write file in Django. Those static file IOs are usually handled by a "pure" web server, e.g., Nginx. – John Wang Aug 27 '12 at 14:28
  • @johnwang I think he means files opened on the local system for some kind or processing, like a `csv` or an image or something. – Pratik Mandrekar Aug 27 '12 at 14:41

1 Answers1

0

Finally I wrote myself a django middleware :

import __builtin__
def newFileClassFactory(oldfile,openfiles):
    class newfile(oldfile):
        def __init__(self, *args):
            self.thepath = args[0]
            print "### OPENING %s ###" % str(self.thepath)
            try:
                oldfile.__init__(self, *args)
            except Exception,e:
                print e
                raise
            openfiles.add(self.thepath)

        def close(self):
            print "### CLOSING %s ###" % str(self.thepath)
            oldfile.close(self)
            openfiles.remove(self.thepath)
    return newfile

class OpenedFiles(object):
    def __init__(self):
        self.oldfile = __builtin__.file
        self.openfiles = set()
        self.newfile = newFileClassFactory(self.oldfile,self.openfiles) 
        self.oldopen = __builtin__.open
        def newopen(*args):
            return self.newfile(*args)
        self.newopen = newopen

    def process_response(self, request, response):        
        if request.path.split('.')[-1].lower() not in ('ico','jpg','jpeg','gif','png','js','css'):
            if self.openfiles:
                print 'Not closed files :'
                print '----------------'
                print '/n'.join(self.openfiles)
            print '*' * 60,' End of Request (%s)' % request.path            
            __builtin__.file = self.oldfile
            __builtin__.open = self.oldopen
        return response

    def process_request(self, request):
        if request.path.split('.')[-1].lower() not in ('ico','jpg','jpeg','gif','png','js','css'):
            __builtin__.file = self.newfile
            __builtin__.open = self.newopen
            print '*' * 60,' Beginning of Request (%s)' % request.path
        return None

Just, add 'your.module.path.OpenedFiles' in settings.py in MIDDLEWARE_CLASSES (at first line if you want to capture what django do in its middlewares), all opened files will be printed on console while running the django built-in server (python manage.py runserver) It will also print the errors that occured and the not closed files.

It is funny to see that many local files are opened by django or applications to generate a dynamic page (templates, session file, cached informations, images to generate on-the-fly thumbnail ...)

Eric
  • 4,821
  • 6
  • 33
  • 60