vendredi 14 novembre 2014

python - Django-debug-toolbar-ligne-profileur montre une seule ligne de sortie, aucun contenu - Stack Overflow


I have a Raspberry Pi sitting in a remote location. It is hooked up to a small homemade circuit and a temperature probe. I've set up the Raspberry Pi to do a few things:



  • Run cron jobs every hour to take a temperature reading and store it locally to a sqlite database

  • Run an Nginx web server

  • Run a uwsgi application server

  • Serve a simple Django app


In that Django app, I have a simple view that does the following:



  1. Hit the DB to get the last 300 temperature recordings

  2. Put those into a Pandas DataFrame

  3. Use Matplotlib to produce a nice SVG graph of the recent temperature history

  4. Fill out a simple template which displays the SVG and also a small HTML table of the recent temperature readings.


Rendering this view takes ~30 seconds. A very long time. So I wanted to see what was taking so long. My guess is that it's all the work related to generating the graphics. But to find out, I wanted to do some profiling.


I installed django-debug-toolbar and also django-debug-toolbar-line-profiler using pip.


I have configured them according to the docs as best I understood. In particular, I've set:


DEBUG = True
TEMPLATE_DEBUG = DEBUG
DEBUG_TOOLBAR_PATCH_SETTINGS = False

MIDDLEWARE_CLASSES = (
'debug_toolbar.middleware.DebugToolbarMiddleware',
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
# Uncomment the next line for simple clickjacking protection:
# 'django.middleware.clickjacking.XFrameOptionsMiddleware',
)

DEBUG_TOOLBAR_PANELS = (
'debug_toolbar.panels.versions.VersionsPanel',
'debug_toolbar.panels.timer.TimerPanel',
'debug_toolbar.panels.settings.SettingsPanel',
'debug_toolbar.panels.headers.HeadersPanel',
'debug_toolbar.panels.sql.SQLPanel',
'debug_toolbar.panels.staticfiles.StaticFilesPanel',
'debug_toolbar.panels.templates.TemplatesPanel',
'debug_toolbar.panels.cache.CachePanel',
'debug_toolbar.panels.signals.SignalsPanel',
'debug_toolbar.panels.logging.LoggingPanel',
'debug_toolbar.panels.redirects.RedirectsPanel',

'debug_toolbar_line_profiler.panel.ProfilingPanel',
)

In addition, INTERNAL_IPS is also set properly.


I have built my view using class-based views. It looks like this:


from django.views.generic import TemplateView
from XXXX.models import TempReading, TempSeries
import numpy as np
import pandas as pd
import matplotlib
from matplotlib.figure import Figure
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
import seaborn as sbn
import StringIO

class TestView(TemplateView):
template_name = 'XXXX/test.html'

def get_context_data(self, **kwargs):
upstairs = TempSeries.objects.get(name='Upstairs')
upstairstemps = upstairs.tempreading_set.all().order_by('-timestamp')[:300]

frame = pd.DataFrame(list(upstairstemps.values()))
frame.set_index('timestamp', inplace=True)

# matplotlib.rcParams['svg.fonttype'] = 'none'

fig = Figure()
ax = fig.add_subplot(1,1,1)
frame['value'].plot(ax=ax)
ax.get_xaxis().grid(color='w', linewidth=1)
ax.get_yaxis().grid(color='w', linewidth=1)

fig.set(facecolor='w')
canvas = FigureCanvas(fig)

imgdata = StringIO.StringIO()
canvas.print_svg(imgdata)

imgstr = imgdata.getvalue()

context = super(TestView, self).get_context_data(**kwargs)
context['svgtext'] = imgstr
context['htmltable'] = frame[:5].to_html()

return context

The code I am most interested in profiling is get_context_data.


When I load the page, the debug-toolbar does in fact show up. And the profiling panel is shown. But all I see is:


{method 'disable' of '_lsprof.Profiler' objects}

Here's a screenshot of the page as it first loads: enter image description here


And here's how it looks on the profiling page: enter image description here


It doesn't seem like it's doing any "line-profiling" at all! I was expecting to see timed results for every line within my class-based view. In particular, for each line within the get_context_data function. What's going on? Any help much appreciated.




Edit on 4/2


Just as a test, I wrote up a dummy view that does not use class-based views. And this seems to work just fine. Here's the new non-class-based-view:


def testview2(request):
df = pd.DataFrame({'a': np.random.randn(10), 'b': np.random.randn(10)})
htmltable = df.to_html()
context = {}
context['htmltable'] = htmltable

return render(request, 'XXXX/test2.html', context)

And that produces the following result in the profiling pane: enter image description here


So that seems to be working fine. Is there some subtlety I'm missing about how debug-toolbar-line-profiler works with class-based views? In the docs, it suggests it will profile any method on the class that does not start with an underscore. Is that incorrect?



I have a Raspberry Pi sitting in a remote location. It is hooked up to a small homemade circuit and a temperature probe. I've set up the Raspberry Pi to do a few things:



  • Run cron jobs every hour to take a temperature reading and store it locally to a sqlite database

  • Run an Nginx web server

  • Run a uwsgi application server

  • Serve a simple Django app


In that Django app, I have a simple view that does the following:



  1. Hit the DB to get the last 300 temperature recordings

  2. Put those into a Pandas DataFrame

  3. Use Matplotlib to produce a nice SVG graph of the recent temperature history

  4. Fill out a simple template which displays the SVG and also a small HTML table of the recent temperature readings.


Rendering this view takes ~30 seconds. A very long time. So I wanted to see what was taking so long. My guess is that it's all the work related to generating the graphics. But to find out, I wanted to do some profiling.


I installed django-debug-toolbar and also django-debug-toolbar-line-profiler using pip.


I have configured them according to the docs as best I understood. In particular, I've set:


DEBUG = True
TEMPLATE_DEBUG = DEBUG
DEBUG_TOOLBAR_PATCH_SETTINGS = False

MIDDLEWARE_CLASSES = (
'debug_toolbar.middleware.DebugToolbarMiddleware',
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
# Uncomment the next line for simple clickjacking protection:
# 'django.middleware.clickjacking.XFrameOptionsMiddleware',
)

DEBUG_TOOLBAR_PANELS = (
'debug_toolbar.panels.versions.VersionsPanel',
'debug_toolbar.panels.timer.TimerPanel',
'debug_toolbar.panels.settings.SettingsPanel',
'debug_toolbar.panels.headers.HeadersPanel',
'debug_toolbar.panels.sql.SQLPanel',
'debug_toolbar.panels.staticfiles.StaticFilesPanel',
'debug_toolbar.panels.templates.TemplatesPanel',
'debug_toolbar.panels.cache.CachePanel',
'debug_toolbar.panels.signals.SignalsPanel',
'debug_toolbar.panels.logging.LoggingPanel',
'debug_toolbar.panels.redirects.RedirectsPanel',

'debug_toolbar_line_profiler.panel.ProfilingPanel',
)

In addition, INTERNAL_IPS is also set properly.


I have built my view using class-based views. It looks like this:


from django.views.generic import TemplateView
from XXXX.models import TempReading, TempSeries
import numpy as np
import pandas as pd
import matplotlib
from matplotlib.figure import Figure
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
import seaborn as sbn
import StringIO

class TestView(TemplateView):
template_name = 'XXXX/test.html'

def get_context_data(self, **kwargs):
upstairs = TempSeries.objects.get(name='Upstairs')
upstairstemps = upstairs.tempreading_set.all().order_by('-timestamp')[:300]

frame = pd.DataFrame(list(upstairstemps.values()))
frame.set_index('timestamp', inplace=True)

# matplotlib.rcParams['svg.fonttype'] = 'none'

fig = Figure()
ax = fig.add_subplot(1,1,1)
frame['value'].plot(ax=ax)
ax.get_xaxis().grid(color='w', linewidth=1)
ax.get_yaxis().grid(color='w', linewidth=1)

fig.set(facecolor='w')
canvas = FigureCanvas(fig)

imgdata = StringIO.StringIO()
canvas.print_svg(imgdata)

imgstr = imgdata.getvalue()

context = super(TestView, self).get_context_data(**kwargs)
context['svgtext'] = imgstr
context['htmltable'] = frame[:5].to_html()

return context

The code I am most interested in profiling is get_context_data.


When I load the page, the debug-toolbar does in fact show up. And the profiling panel is shown. But all I see is:


{method 'disable' of '_lsprof.Profiler' objects}

Here's a screenshot of the page as it first loads: enter image description here


And here's how it looks on the profiling page: enter image description here


It doesn't seem like it's doing any "line-profiling" at all! I was expecting to see timed results for every line within my class-based view. In particular, for each line within the get_context_data function. What's going on? Any help much appreciated.




Edit on 4/2


Just as a test, I wrote up a dummy view that does not use class-based views. And this seems to work just fine. Here's the new non-class-based-view:


def testview2(request):
df = pd.DataFrame({'a': np.random.randn(10), 'b': np.random.randn(10)})
htmltable = df.to_html()
context = {}
context['htmltable'] = htmltable

return render(request, 'XXXX/test2.html', context)

And that produces the following result in the profiling pane: enter image description here


So that seems to be working fine. Is there some subtlety I'm missing about how debug-toolbar-line-profiler works with class-based views? In the docs, it suggests it will profile any method on the class that does not start with an underscore. Is that incorrect?


0 commentaires:

Enregistrer un commentaire