8

I want to check the execution time of views in my site. This can be done by decorators, but since I have dozens of views I thought of doing it in a middleware, saving the initial time in a dictionary with the request as a key (see below), but I'm worried about assumptions I made (see farther below):

class SlowWarningMiddleware:

    def __init__(self):
        self.time_tracking = {}

    def process_view(self, request, view_func, view_args, view_kwargs):
        self.time_tracking[request] = time.time() 

    def process_response(self, request, response):
        if request not in self.time_tracking:
            return response
        delta = time.time() - self.time_tracking[request]

    def process_exception(self, request, exception):
        if request not in self.time_tracking:
            return
        delta = time.time() - self.time_tracking[request]

this code assumes two points:

  1. The same middleware instance handles the pre-view and post-view logic.
  2. The request instance remains the same instance pre-view and post-view.

are these assumptions safe? is this middleware a good idea?

Сыч
  • 930
  • 1
  • 8
  • 15
Iftah
  • 9,512
  • 2
  • 33
  • 45

2 Answers2

7

Reading Is Django middleware thread safe? gave me a better idea:
To add an attribute to the request object (ie request.start_time = time.time() before the view is executed).

This avoids assumption 1 and removes the dangerous potential to collect 'zombie' items in the dictionary that will never be cleared.

This also some somewhat reduces assumption 2, because if a new copy of request is made at some point it will still work if the attributes are copied (as done in python copy module).

And even as a bonus its less code, less error prone and more readable :)

Community
  • 1
  • 1
Iftah
  • 9,512
  • 2
  • 33
  • 45
1

Use this simply view to calculate the execution time , it works also for views that need user login, it displays execution time in a simple page

 def test(request):
     from django.test.client import Client
     import time

     c = Client()

     #client login if needed
     response = c.post('/login/', {'username': 'admin', 'password': 'password'})

     start = time.time()
     response = c.get('/pagetotest/')

     #print response
     #print 'Finished, time: ', time.time() - start # output to console
     end=time.time() - start
     return render(request,'loadingtime.html',{'time':end})

For you case, using a loop for all your pages hope it will help someone

Cherif KAOUA
  • 834
  • 12
  • 21