2014-03-30 6 views
10

Ich habe einen Raspberry Pi an einem entfernten Ort sitzen. Es ist an einen kleinen hausgemachten Stromkreis und eine Temperatursonde angeschlossen. Ich habe das Raspberry Pi eingerichtet, ein paar Dinge zu tun:Django-Debug-Toolbar-Line-Profiler zeigt nur eine einzige Zeile der Ausgabe, kein Inhalt

  • Run cron Jobs jede Stunde eine Temperaturmessung zu nehmen und speichern Sie es lokal zu einer SQLite-Datenbank
  • Führen Sie einen Nginx Web-Server
  • Run ein uwsgi Anwendungsserver
  • eine einfache Anwendung Django Serve

In diesem Django app, ich habe eine einfache Ansicht, die die folgenden:

  1. die DB Hit der letzten 300 Temperaturaufzeichnungen
  2. diejenigen in eine Pandas DataFrame
  3. Verwenden Matplotlib Setzen Sie bekommen ein schönes SVG Graph der letzten Temperaturverlauf zu erzeugen
  4. eine einfache Vorlage ausfüllen, die die anzeigt SVG und auch eine kleine HTML-Tabelle der letzten Temperaturmessungen.

Das Rendern dieser Ansicht dauert ~ 30 Sekunden. Eine sehr lange Zeit. Also wollte ich sehen, was so lange dauert. Meine Vermutung ist, dass es die ganze Arbeit ist, die mit dem Generieren der Grafiken verbunden ist. Aber um das herauszufinden, wollte ich etwas Profiling machen.

Ich installierte django-debug-toolbar und auch django-debug-toolbar-line-profiler mit Pip.

Ich habe sie nach den Dokumenten so konfiguriert, wie ich es am besten verstand. Insbesondere habe ich eingestellt:

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', 
) 

Zusätzlich INTERNAL_IPS auch richtig eingestellt ist.

Ich habe meine Ansicht mit klassenbasierten Ansichten erstellt. Es sieht wie folgt aus:

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 

Der Code Ich bin am meisten interessiert Profilierung ist get_context_data.

Wenn ich die Seite lade, wird die Debug-Toolbar angezeigt. Und das Profiling-Panel wird angezeigt. Aber alles, was ich sehe, ist:

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

Hier ist ein Screenshot der Seite, wie es zunächst Lasten: enter image description here

Und hier ist, wie es auf der Profilseite aussieht: enter image description here

Es ist nicht Scheint so, als würde es überhaupt "Line-Profiling" machen! Ich habe erwartet, dass für jede Zeile in meiner klassenbasierten Ansicht zeitgesteuerte Ergebnisse angezeigt werden. Insbesondere für jede Zeile innerhalb der get_context_data Funktion. Was ist los? Jede Hilfe wird sehr geschätzt.


Bearbeiten auf 4/2

Nur als Test, schrieb ich eine Dummy-Ansicht auf, dass nicht Verwendung klassenbasierte Ansichten. Und das scheint gut zu funktionieren. Hier ist der neue nicht-klassenbasierte Blick:

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) 

Und das erzeugt das folgende Ergebnis im Profilierungsbereich: enter image description here

Damit scheint gut zu funktionieren. Gibt es eine Feinheit, die mir fehlt, wie debug-toolbar-line-profiler mit klassenbasierten Ansichten funktioniert? In den Dokumenten wird vorgeschlagen, dass eine beliebige Methode in der Klasse profiliert wird, die nicht mit einem Unterstrich beginnt. Ist das falsch?

+0

Was ist Ihre Arbeitsumgebung? Windows, Linux/UNIX oder Mac? – OrangeCube

+0

Es ist auf einem Raspberry Pi – 8one6

+0

entfaltet Wenn es weitere Informationen, die hilfreich wären, wäre, lass es mich wissen. – 8one6

Antwort

0

Da Sie dies auf einem Chip hosten, würde ich Ihnen dringend empfehlen, die Serverseite so einfach wie möglich zu halten und die komplizierte Logikbehandlung auf die Clientseite zu verlagern.

Ja, vertrauen JS kann so viel wie Python tun. und es wird nicht auf deinem Server sein. All diese Grafikzeichnungen, auch Template-Rendering, sollten Sie auf die Client-Seite verschieben. Dies wird definitiv die Zeit für die Seitenlieferung für ein Chip-ähnliches Gerät beseitigen.

Wie für das Debugging, warum debuggen Sie es nicht auf echten PC und dann verschieben Sie es auf Ras-Pi. Sie können eine einfache Logging-Logik hinzufügen, um die Abschnitte zu markieren, die Sie untersuchen möchten.

+2

Vielen Dank für Ihre Antwort. Ihre Anmerkung zum Verschieben der Verarbeitung zur Clientseite zur Verbesserung der Leistung ist angemessen. Aber es geht nicht wirklich darum, die Leistung zu verbessern ... es geht darum, dass das Benchmarking-Tool "wie angekündigt" funktioniert. Irgendwelche Gedanken darüber, warum der Profiler nicht funktioniert? – 8one6

0

Ich bemerkte dieses passiert, als ich meine Ansichten mit @csrf_exempt schmückte; Einmal entfernt, funktionierte der Profiler gut.

Nicht sicher, warum es das Problem verursacht, aber das für mich behoben.